home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Source.bin / ImageListBox.java < prev    next >
Text File  |  1998-10-12  |  115KB  |  3,598 lines

  1. package symantec.itools.awt;
  2.  
  3.  
  4. import java.awt.Panel;
  5. import java.awt.Dimension;
  6. import java.awt.Component;
  7. import java.awt.Image;
  8. import java.awt.Graphics;
  9. import java.awt.Scrollbar;
  10. import java.awt.Font;
  11. import java.awt.FontMetrics;
  12. import java.awt.Color;
  13. import java.awt.Rectangle;
  14. import java.awt.SystemColor;
  15. import java.util.Vector;
  16. import java.awt.image.MemoryImageSource;
  17. import java.awt.event.MouseEvent;
  18. import java.awt.event.KeyEvent;
  19. import java.awt.event.ActionEvent;
  20. import java.awt.event.ActionListener;
  21. import java.awt.event.ItemEvent;
  22. import java.awt.event.ItemListener;
  23. import java.awt.event.AdjustmentEvent;
  24. import java.beans.PropertyVetoException;
  25. import java.beans.PropertyChangeListener;
  26. import java.beans.VetoableChangeListener;
  27. import java.awt.AWTEvent;
  28. import java.awt.AWTEventMulticaster;
  29. import java.net.URL;
  30. import symantec.itools.awt.util.ColorUtils;
  31. import java.util.ResourceBundle;
  32. import java.text.MessageFormat;
  33.  
  34. //     03/02/97    RKM    In ctor, make certain bar size is correct for Macs
  35. //     03/21/97    RKM    Removed repaint hack from paint
  36. //     03/21/97    LAB    Updated to Java 1.1.  Removed setDirectNotify(boolean bDirectNotify),
  37. //                    as it is not needed with the new event model.
  38. //     07/18/97    LAB    Added add/removeNotify to handle event listener registration.
  39. //  07/29/97    CAR marked fields transient as needed
  40. //                  inner adaptor classes implement java.io.Serializable
  41. //                  implemented readObject
  42. //                  added property imageURL (ListItem needs to store URL in addition to Image for serialization)
  43. //  08/09/97    LAB    Removed ListBoxFont property and made the standard Font property do it's work. Removed
  44. //                    DisabledTextColor property.  Removed DefaultEnabledTextColor property.  Added a getter to the
  45. //                    EnabledTextColor property.  Removed dependency on bOsFlag private data member.  Removed the bOsFlag
  46. //                    member. Removed SelectImage and dependencies.  Removed default initialization of Font and
  47. //                    Background color in the constructor.  Now hide the scrollbars before adding them to their
  48. //                    container.  Made the border calculate it's colors based on the background color. Deprecated
  49. //                    preferredSize and minimumSize methods in favor of getPreferredSize and getMinimumSize.
  50. //    08/15/97    LAB    Reworked the way colors were calculated to avoid NullPointerExceptions,
  51. //                    and potential redraw problems.  Now colors are recalculated in paint,
  52. //                    if needed.
  53. //  08/22/97    CAR Fixed bug re: scrollbars were scrolling in the reverse directions
  54. //                  Fixed bug on Windows platform re: ImageListBox in combomode would not display all of list
  55. //                  Fixed bug on Windows platform re: Scrollbars would not appear
  56. //                  Fixed bug in setSelectedItem re: item was not selected or highlighted
  57. //                  Fixed bug in setSelectedIndex re: first item selected was not highlighted
  58. //                  Fixed bug in delSelectedItem re: item not deleted and NegativeArraySizeException
  59. //                  for non-multiple selection and ArrayIndexOUtOfBoundsException for multiple selection
  60. //  08/25/97     ADI Fixed bug Scrollbars:
  61. //                  VBar.setValues(nTopRow, visibleRows, 0, nItems - visibleRows);
  62. //                  modified in:
  63. //                  VBar.setValues(nTopRow, visibleRows, 0, nItems);
  64. //  08/31/97    CAR Fixed bug re: selection of item while multiple selection set to true leads to ArrayIndexOutOfBoundsException
  65. //                  Fixed bug re: last item in multiple selection will not delete
  66. //                  Fixed bug re: after deleting an item that index could not be re-selected w/o first selecting another item
  67. //    09/23/97    RKM    Fixed bug in setFont - was not handling setFont(null)
  68. //    10/01/97    LAB    Fixed a bug where the barSize variable was not getting set correctly, which
  69. //                    resulted in the scrollbars not showing up properly (Addresses Mac Bug #7571
  70. //                    and #7538).  Fixed a bug when in ComboBoxMode, you could autoscroll down,
  71. //                    but not up (changed yAdj from 0 in setComboBoxMode).  Added accessors for
  72. //                    CellHeight and BorderWidth to allow ComboBox (and anyone else) to access them.
  73. //                    Removed the use of yAdj everywhere except in mouseCalcIndex where its use
  74. //                    makes sense.
  75. //  03/02/98    DS  Added isFocusedTraversable & call to RequestFocus to MousePressed
  76.  
  77. /**
  78.  * A box containing a list of images and/or text.
  79.  * <p>
  80.  * Use an ImageListBox to display a set of images and/or text that the user
  81.  * can select.
  82.  * The user cannot enter text in an ImageListBox.
  83.  * <p>
  84.  * @version 1.1, June 7, 1997
  85.  * @author Symantec
  86.  */
  87. public class ImageListBox extends Panel implements java.awt.ItemSelectable
  88. {
  89.     /**
  90.      * The ID of the event posted when the image portion of a list item
  91.      * is selected.
  92.      */
  93.     public static final int EVT_IMAGE_SELECT = 0x4004;
  94.  
  95.     /**
  96.      * Defines the "regular" (lowered) border style. This makes the list box
  97.      * appear lower than the surrounding area.
  98.      * @see #setBorderType
  99.      * @see #getBorderType
  100.      */
  101.     public static final int BORDER_REGULAR = 0;
  102.  
  103.     /**
  104.      * Defines the "no border" style. This indicates the list box will have no
  105.      * border drawn around it.
  106.      * @see #setBorderType
  107.      * @see #getBorderType
  108.      */
  109.     public static final int BORDER_NONE = 1;
  110.  
  111.     /**
  112.      * Defines the width of all images displayed in the list, in pixels.
  113.      */
  114.     public static final int IMAGE_WIDTH = 19;
  115.  
  116.     /**
  117.      * Constructs a default ImageListBox.
  118.      * A default ImageListBox has no label, will size to show all of the
  119.      * existing list items when automatically laid out, and allows single list
  120.      * item selection.
  121.      */
  122.     public ImageListBox()
  123.     {
  124.         this("", -1, false);
  125.     }
  126.  
  127.     /**
  128.      * Constructs an ImageListBox with the specified label. It will size to show
  129.      * all of the existing list items when automatically laid out, and allows
  130.      * single list item selection.
  131.      * Note: he label of an ImageListBox does not get displayed.
  132.      *
  133.      * @param label the label of the list box (not displayed)
  134.      */
  135.     public ImageListBox(String label)
  136.     {
  137.         this(label, -1, false);
  138.     }
  139.  
  140.     /**
  141.      * Constructs an ImageListBox with the specified label and
  142.      * conditionally allows multiple selections.
  143.      * It will size to show all of the existing list items when
  144.      * automatically laid out.
  145.      * Note: the label of an ImageListBox does not get displayed.
  146.      * @param label the name label of the list box (not displayed)
  147.      * @param bMultipleSelections if true then multiple selections are allowed;
  148.      * if false only single item selections are allowed
  149.      */
  150.     public ImageListBox(String label, boolean bMultipleSelections)
  151.     {
  152.         this(label, -1, bMultipleSelections);
  153.     }
  154.  
  155.     /**
  156.      * Constructs an ImageListBox with the specified label, the
  157.      * specified number of visible rows,  and conditionally allows multiple
  158.      * list item selection.
  159.      * @param slabel the label of the list box (not displayed)
  160.      * @param rows the number of row items to show.  If rows is less than or equal
  161.      * to zero,
  162.      * it will size to show all of the existing list items when
  163.      * automatically laid out.
  164.      * @param bMultipleSelections if true then multiple selections are allowed;
  165.      * if false only single item selections are allowed
  166.      */
  167.     public ImageListBox(String slabel, int rows, boolean bMultipleSelections)
  168.     {
  169.         items = new Vector();
  170.  
  171.         ilbLabel = slabel;
  172.         rowsToShow = rows;
  173.         this.bMultipleSelections = bMultipleSelections;
  174.  
  175.         setLayout(null);
  176.  
  177.         VBar = new Scrollbar();
  178.         VBar.setBackground(SystemColor.control);
  179.         VBar.hide();
  180.         add(VBar);
  181.  
  182.         HBar = new Scrollbar(Scrollbar.HORIZONTAL);
  183.         HBar.setBackground(SystemColor.control);
  184.         HBar.hide();
  185.         add(HBar);
  186.  
  187.         //Initilize the cached color.
  188.         cachedBackground    = getBackground();
  189.      }
  190.  
  191.     /**
  192.      * @deprecated
  193.      * see constructor ImageListBox(String slabel, int rows, boolean bMultipleSelections)
  194.      */
  195.     public ImageListBox(Component parent, String slabel, int rows, boolean bMultipleSelections)
  196.     {
  197.         this(slabel, rows, bMultipleSelections);
  198.     }
  199.  
  200.     /**
  201.      * @deprecated
  202.      * see constructor ImageListBox(String slabel, int rows, boolean bMultipleSelections)
  203.      */
  204.     public ImageListBox(Component parent, String label)
  205.     {
  206.         this(label);
  207.     }
  208.  
  209.     //--------------------------------------------------
  210.     // accessor methods
  211.     //--------------------------------------------------
  212.  
  213.     /**
  214.      * Sets ImageListBox "ComboBox mode".
  215.      * "ComboBox mode" allows the selection point to follow
  216.      * the mouse even when the mouse button is not down.
  217.      * This only applies when the ImageListBox is not allowing multiple
  218.      * selections.
  219.      * @exception PropertyVetoException
  220.      * if the specified property value is unacceptable
  221.      * @see #isComboMode
  222.      */
  223.     public void setComboMode(boolean cond) throws PropertyVetoException
  224.     {
  225.         if(bComboMode != cond)
  226.         {
  227.             Boolean oldValue = new Boolean(bComboMode);
  228.             Boolean newValue = new Boolean(cond);
  229.  
  230.             vetos.fireVetoableChange("ComboMode", oldValue, newValue);
  231.  
  232.             bComboMode = cond;
  233.             yAdj = 3;
  234.             invalidate();
  235.  
  236.             changes.firePropertyChange("ComboMode", oldValue, newValue);
  237.         }
  238.     }
  239.  
  240.     /**
  241.      * Gets the current "ComboBox mode" setting.
  242.      * "ComboBox mode" allows the selection point to follow
  243.      * the mouse even when the mouse button is not down.
  244.      * This only applies when the ImageListBox is not allowing multiple
  245.      * selections.
  246.      * @return true if in "ComboBox mode", otherwise false
  247.      * @see #setComboMode
  248.      */
  249.     public boolean isComboMode()
  250.     {
  251.         return bComboMode;
  252.     }
  253.  
  254.     /**
  255.      * @deprecated
  256.      * @see #isComboMode
  257.      */
  258.     public boolean getComboMode()
  259.     {
  260.         return isComboMode();
  261.     }
  262.  
  263.     /**
  264.      * Sets the number of rows to display in the ImageListBox.
  265.      * This affects the dimensions returned by getPreferredSize and determines
  266.      * the number of rows displayed when this component is automatically laid out.
  267.      * @param rows number of rows to automatically display
  268.      * @exception PropertyVetoException
  269.      * if the specified property value is unacceptable
  270.      * @see #getRowsToShow
  271.      */
  272.     public void setRowsToShow(int rows) throws PropertyVetoException
  273.     {
  274.         if(rowsToShow != rows)
  275.         {
  276.             Integer oldValue = new Integer(rowsToShow);
  277.             Integer newValue = new Integer(rows);
  278.  
  279.             vetos.fireVetoableChange("RowsToShow", oldValue, newValue);
  280.  
  281.             rowsToShow = rows;
  282.             invalidate();
  283.  
  284.             changes.firePropertyChange("RowsToShow", oldValue, newValue);
  285.         }
  286.     }
  287.  
  288.     /**
  289.      * Gets the current number of rows to display.
  290.      * This affects the dimensions returned by getPreferredSize and determines
  291.      * the number of rows displayed when this component is automatically laid out.
  292.      * @return the current number of rows to automatically display
  293.      * @see #setRowsToShow
  294.      */
  295.     public int getRowsToShow()
  296.     {
  297.         return rowsToShow;
  298.     }
  299.  
  300.     /**
  301.      * Sets the vertical scrollbar visibility flag.
  302.      * @param cond if true, the vertical scrollbar will be made
  303.      * visible when necessary; if false, the vertical scrollbar
  304.      * will never be made visible
  305.      * @exception PropertyVetoException
  306.      * if the specified property value is unacceptable
  307.      * @see #isShowVerticalScroll
  308.      */
  309.     public void setShowVerticalScroll(boolean cond) throws PropertyVetoException
  310.     {
  311.         if(bAllowShowVBar != cond)
  312.         {
  313.             Boolean oldValue = new Boolean(bAllowShowVBar);
  314.             Boolean newValue = new Boolean(cond);
  315.  
  316.             vetos.fireVetoableChange("ShowVerticalScroll", oldValue, newValue);
  317.  
  318.             bAllowShowVBar = cond;
  319.             invalidate();
  320.  
  321.             changes.firePropertyChange("ShowVerticalScroll", oldValue, newValue);
  322.         }
  323.     }
  324.  
  325.     /**
  326.      * Gets the current vertical scrollbar visibility flag.
  327.      * @return true if the vertical scrollbar will be made
  328.      * visible when necessary; false if the vertical scrollbar
  329.      * will never be made visible
  330.      * @see #setShowVerticalScroll
  331.      */
  332.     public boolean isShowVerticalScroll()
  333.     {
  334.         return bAllowShowVBar;
  335.     }
  336.  
  337.     /**
  338.      * @deprecated
  339.      * @see #isShowVerticalScroll
  340.      */
  341.     public boolean getShowVerticalScroll()
  342.     {
  343.         return isShowVerticalScroll();
  344.     }
  345.  
  346.     /**
  347.      * Sets the horizontal scrollbar visibility flag.
  348.      * @param cond if true, the horizontal scrollbar will be made
  349.      * visible when necessary; if false, the horizontal scrollbar
  350.      * will never be made visible
  351.      * @exception PropertyVetoException
  352.      * if the specified property value is unacceptable
  353.      * @see #isShowHorizontalScroll
  354.      */
  355.     public void setShowHorizontalScroll(boolean cond) throws PropertyVetoException
  356.     {
  357.         if(bAllowShowHBar != cond)
  358.         {
  359.             Boolean oldValue = new Boolean(bAllowShowHBar);
  360.             Boolean newValue = new Boolean(cond);
  361.  
  362.             vetos.fireVetoableChange("ShowHorizontalScroll", oldValue, newValue);
  363.  
  364.             bAllowShowHBar = cond;
  365.             invalidate();
  366.  
  367.             changes.firePropertyChange("ShowHorizontalScroll", oldValue, newValue);
  368.         }
  369.     }
  370.  
  371.     /**
  372.      * Gets the current horizontal scrollbar visibility flag.
  373.      * @return true if the horizontal scrollbar will be made
  374.      * visible when necessary; false if the horizontal scrollbar
  375.      * will never be made visible
  376.      * @see #setShowHorizontalScroll
  377.      */
  378.     public boolean isShowHorizontalScroll()
  379.     {
  380.         return bAllowShowHBar;
  381.     }
  382.  
  383.     /**
  384.      * @deprecated
  385.      * @see #isShowHorizontalScroll
  386.      */
  387.     public boolean getShowHorizontalScroll()
  388.     {
  389.         return isShowHorizontalScroll();
  390.     }
  391.  
  392.     /**
  393.      * Sets the border type of the ImageListBox.
  394.      * A regular border makes the list box appear lower than the surrounding area.
  395.      * @param type new border type, BORDER_REGULAR or BORDER_NONE
  396.      * @exception PropertyVetoException
  397.      * if the specified property value is unacceptable
  398.      * @see #getBorderType
  399.      * @see #BORDER_REGULAR
  400.      * @see #BORDER_NONE
  401.      */
  402.     public void setBorderType(int type) throws PropertyVetoException
  403.     {
  404.         if(borderType != type)
  405.         {
  406.             Integer oldValue = new Integer(borderType);
  407.             Integer newValue = new Integer(type);
  408.  
  409.             vetos.fireVetoableChange("BorderType", oldValue, newValue);
  410.  
  411.             borderType = type;
  412.             if (type == BORDER_REGULAR)
  413.             {
  414.                 borderWidth = 4;
  415.                 halfBorderWidth = 2;
  416.             }
  417.             else
  418.             {
  419.                 borderWidth = 0;
  420.                 halfBorderWidth = 0;
  421.             }
  422.             invalidate();
  423.  
  424.             changes.firePropertyChange("BorderType", oldValue, newValue);
  425.         }
  426.     }
  427.  
  428.     /**
  429.      * Gets the current border type of the ImageListBox.
  430.      * A regular border makes the list box appear lower than the surrounding area.
  431.      * @return the current border type, BORDER_REGULAR or BORDER_NONE
  432.      * @see #setBorderType
  433.      * @see #BORDER_REGULAR
  434.      * @see #BORDER_NONE
  435.      */
  436.     public int getBorderType()
  437.     {
  438.         return borderType;
  439.     }
  440.  
  441.     /**
  442.      * Conditionally show a border around the cell at the specified index.
  443.      * Cell borders are always shown as a solid single-pixel wide line around
  444.      * the cell.
  445.      * @param index the zero-relative index of the cell
  446.      * @param bOn true to show the cell borders; false to not show them
  447.      * @exception PropertyVetoException
  448.      * if the specified property value is unacceptable
  449.      * @see #setCellBorders
  450.      */
  451.     public void setCellBorder(int index, boolean bOn) throws PropertyVetoException
  452.     {
  453.         if (validIndex(index))
  454.         {
  455.             ListItem li = (ListItem) items.elementAt(index);
  456.             if (li.bCellBorder != bOn)
  457.             {
  458.                 Boolean oldValue = new Boolean(li.bCellBorder);
  459.                 Boolean newValue = new Boolean(bOn);
  460.                 vetos.fireVetoableChange("CellBorder", oldValue, newValue);
  461.                 li.bCellBorder = bOn;
  462.                 li.bDirty = true;
  463.                 invalidate();
  464.                 changes.firePropertyChange("CellBorder", oldValue, newValue);
  465.             }
  466.         }
  467.     }
  468.  
  469.     /**
  470.      * Sets the ImageListBox cell border display default, and
  471.      * resets all items to have the border conditionally.
  472.      * Cell borders are always shown as a solid single-pixel wide line around
  473.      * the cell.
  474.      * @param bOn true for "grid lines on by default" mode,
  475.      * false for "grid lines off by default" mode.
  476.      * @exception PropertyVetoException
  477.      * if the specified property value is unacceptable
  478.      * @see #setCellBorder
  479.      * @see #isCellBorders
  480.      */
  481.     public void setCellBorders(boolean bOn) throws PropertyVetoException
  482.     {
  483.         if(bCellBorders != bOn)
  484.         {
  485.             Boolean oldValue = new Boolean(bCellBorders);
  486.             Boolean newValue = new Boolean(bOn);
  487.             vetos.fireVetoableChange("CellBorders", oldValue, newValue);
  488.  
  489.             bCellBorders = bOn;
  490.  
  491.             int s = items.size();
  492.             ListItem li = null;
  493.  
  494.             for (int x = 0; x < s; x++)
  495.             {
  496.                 li = (ListItem) items.elementAt(x);
  497.                 li.bCellBorder = bOn;
  498.             }
  499.             bAllDirty = true;
  500.             invalidate();
  501.             changes.firePropertyChange("CellBorders", oldValue, newValue);
  502.         }
  503.     }
  504.  
  505.     /**
  506.      * Gets the current default cell border display mode.
  507.      * Cell borders are always shown as a solid single-pixel wide line around
  508.      * the cell.
  509.      * @return true if the "grid lines on by default" mode is on, otherwise false
  510.      * @see #setCellBorders
  511.      */
  512.     public boolean isCellBorders()
  513.     {
  514.         return bCellBorders;
  515.     }
  516.  
  517.     /**
  518.      * @deprecated
  519.      * @see #isCellBorders
  520.      */
  521.     public boolean getCellBorders()
  522.     {
  523.         return isCellBorders();
  524.     }
  525.  
  526.     /**
  527.      * Sets the text color for an item at the given index.
  528.      * @param index the zero-relative index of the item
  529.      * @param color the color, null to use the default text color
  530.      * @exception PropertyVetoException
  531.      * if the specified property value is unacceptable
  532.      */
  533.     public void setEnabledTextColor(int index, Color color) throws PropertyVetoException
  534.     {
  535.         if (validIndex(index))
  536.         {
  537.             ListItem tempItem = ((ListItem)items.elementAt(index));
  538.             if (!symantec.itools.util.GeneralUtils.objectsEqual(tempItem, color))
  539.             {
  540.                 Color oldValue = tempItem.color;
  541.  
  542.                 vetos.fireVetoableChange("EnabledTextColor", oldValue, color);
  543.  
  544.                 tempItem.color = color;
  545.  
  546.                 changes.firePropertyChange("EnabledTextColor", oldValue, color);
  547.             }
  548.         }
  549.     }
  550.  
  551.     /**
  552.      * Gets the text color for an item at the given index.
  553.      * @param index the zero-relative index of the item
  554.      * @return the color, null if the default text color is used
  555.      * or the index is not valid.
  556.      */
  557.     public Color getEnabledTextColor(int index)
  558.     {
  559.         if (validIndex(index))
  560.         {
  561.             ListItem tempItem = ((ListItem)items.elementAt(index));
  562.  
  563.             return(tempItem.color);
  564.         }
  565.         return null;
  566.     }
  567.  
  568.     /**
  569.      * Sets the mode of the ImageListBox to "MultiColumnListBox
  570.      * mode".  This method always sets the border type to BORDER_NONE,
  571.      * the "ComboBox mode" to be false,
  572.      * and conditionally sets whether the grid should be displayed.
  573.      * @param bCellBorders true to display the cell grid,
  574.      * false to not display the grid
  575.      * @exception PropertyVetoException
  576.      * if the specified property value is unacceptable
  577.      * @see #BORDER_NONE
  578.      */
  579.     public synchronized void setMultiColumnMode(boolean bCellBorders) throws PropertyVetoException
  580.     {
  581.         if(isCellBorders() != bCellBorders)
  582.         {
  583.             setComboMode(false);
  584.             setBorderType(BORDER_NONE);
  585.             setCellBorders(bCellBorders);
  586.             yAdj = 2;
  587.         }
  588.     }
  589.  
  590.     /**
  591.      * Initializes the list with the string array. Any pre-existing items are
  592.      * lost.
  593.      * @param items the new list items
  594.      * @exception PropertyVetoException
  595.      * if the specified property value is unacceptable
  596.      * @see #getListItems
  597.      * @see #setListItems(java.lang.String[])
  598.      * @see #addItem(java.lang.String)
  599.      * @see #addItem(java.lang.String, boolean)
  600.      * @see #addItem(java.awt.Image, java.lang.String)
  601.      * @see #addItem(java.awt.Image, java.lang.String, boolean)
  602.      * @see #addItem(java.awt.Image, java.lang.String, boolean, java.awt.Color)
  603.      */
  604.     public void setListItems(String[] items) throws PropertyVetoException
  605.     {
  606.         String[] oldValue = getListItems();
  607.         vetos.fireVetoableChange("ListItems", oldValue, items);
  608.  
  609.         clear();
  610.         for (int i = 0; i < items.length; ++i)
  611.         {
  612.             addItem(items[i]);
  613.         }
  614.  
  615.         changes.firePropertyChange("ListItems", oldValue, items);
  616.     }
  617.  
  618.     /**
  619.      * Returns the current list as an array.
  620.      * @return String[] current list
  621.      * @see #setListItems
  622.      */
  623.     public String[] getListItems()
  624.     {
  625.         int len = countItems();
  626.         String[] items = new String[len];
  627.         for (int i = 0; i < len; ++i)
  628.         {
  629.             items[i] = getItem(i);
  630.         }
  631.         return items;
  632.     }
  633.  
  634.     /**
  635.      * Set a flag indicating that the item at the given zero-relative index
  636.      * has been edited.
  637.      * @param index the zero-relative position of the item
  638.      * @param bCond the "edited" flag
  639.      * @exception PropertyVetoException
  640.      * if the specified property value is unacceptable
  641.      * @see #isEdited
  642.      */
  643.     public void setEdited(int index, boolean bCond) throws PropertyVetoException
  644.     {
  645.         if (validIndex(index))
  646.         {
  647.             ListItem tempItem = ((ListItem)items.elementAt(index));
  648.             if(tempItem.bEdited != bCond)
  649.             {
  650.                 Boolean oldValue = new Boolean(tempItem.bEdited);
  651.                 Boolean newValue = new Boolean(bCond);
  652.                 vetos.fireVetoableChange("Edited", oldValue, newValue);
  653.  
  654.                 tempItem.bEdited = bCond;
  655.  
  656.                 changes.firePropertyChange("Edited", oldValue, newValue);
  657.             }
  658.         }
  659.     }
  660.  
  661.     /**
  662.      * Gets the "edited" flag state for the item at the given
  663.      * zero-relative index.
  664.      * @param index the zero-relative position of the item
  665.      * @return true if flagged as edited, false if not
  666.      * @see #setEdited
  667.      */
  668.     public boolean isEdited(int index)
  669.     {
  670.         if (validIndex(index))
  671.         {
  672.             ListItem tempItem = ((ListItem)items.elementAt(index));
  673.             return tempItem.bEdited;
  674.         }
  675.  
  676.         return false;
  677.     }
  678.  
  679.     /**
  680.      * @deprecated
  681.      * @see #isEdited
  682.      */
  683.     public boolean getEdited(int index)
  684.     {
  685.         return isEdited(index);
  686.     }
  687.  
  688.     /**
  689.      * Sets whether this list should allow multiple selections
  690.      * or not.
  691.      * @param cond whether to allow multiple selections
  692.      * @exception PropertyVetoException
  693.      * if the specified property value is unacceptable
  694.      * @see #allowsMultipleSelections
  695.      */
  696.     public void setMultipleSelections(boolean cond) throws PropertyVetoException
  697.     {
  698.         if (bMultipleSelections != cond)
  699.         {
  700.             Boolean oldValue = new Boolean(bMultipleSelections);
  701.             Boolean newValue = new Boolean(cond);
  702.             vetos.fireVetoableChange("MultipleSelections", oldValue, newValue);
  703.  
  704.             if (!cond)  // deselect first because deselect works differently according to bMultipleSelections flag
  705.                 deselectAll();
  706.             bMultipleSelections = cond;
  707.  
  708.             changes.firePropertyChange("MultipleSelections", oldValue, newValue);
  709.         }
  710.     }
  711.  
  712.     /**
  713.      * Returns true if this list allows multiple selections.
  714.      * @return true if multiple selections allowed, false otherwise
  715.      * @see #setMultipleSelections
  716.      */
  717.     public boolean isMultipleSelections()
  718.     {
  719.         return bMultipleSelections;
  720.     }
  721.  
  722.     /**
  723.      * Conditionally enables the specified item in the list.
  724.      * @param index the zero-relative position of the item
  725.      * @param cond if true, enable the item; if false, disable the
  726.      * item
  727.      * @exception PropertyVetoException
  728.      * if the specified property value is unacceptable
  729.      * @see #isEnabled
  730.      */
  731.     public void setEnabled(int index, boolean cond) throws PropertyVetoException
  732.     {
  733.         if (validIndex(index))
  734.         {
  735.             ListItem tempItem = ((ListItem)items.elementAt(index));
  736.             if(tempItem.bEnabled != cond)
  737.             {
  738.                 Boolean oldValue = new Boolean(tempItem.bEnabled);
  739.                 Boolean newValue = new Boolean(cond);
  740.                 vetos.fireVetoableChange("Enabled", oldValue, newValue);
  741.  
  742.                 tempItem.bEnabled = cond;
  743.                 if(!cond)
  744.                 {
  745.                     deselect(index);
  746.                 }
  747.                 tempItem.bDirty = true;
  748.                 if (!bInternalBlockPaint)
  749.                     repaint();
  750.  
  751.                 changes.firePropertyChange("Enabled", oldValue, newValue);
  752.             }
  753.         }
  754.     }
  755.  
  756.     /**
  757.      * Gets the enabled state of a specific item in the list.
  758.      * @param index the zero-relative position of the item in the list
  759.      * @return true if the item is enabled, false
  760.      * if the item is disabled.
  761.      * @see #setEnabled(int, boolean)
  762.      */
  763.     public boolean isEnabled(int index)
  764.     {
  765.         if (validIndex(index))
  766.         {
  767.             ListItem tempItem = ((ListItem)items.elementAt(index));
  768.             return tempItem.bEnabled;
  769.         }
  770.  
  771.         return false;
  772.     }
  773.  
  774.     /**
  775.      * Changes the text associated with the item at the specified
  776.      * zero-relative index.
  777.      * @param index the zero-relative position of the item
  778.      * @param text the new text to associate with the item
  779.      * @exception PropertyVetoException
  780.      * if the specified property value is unacceptable
  781.      * @see #getText
  782.      */
  783.     public void setText(int index, String text) throws PropertyVetoException
  784.     {
  785.         if (validIndex(index))
  786.         {
  787.             ListItem tempItem = ((ListItem)items.elementAt(index));
  788.  
  789.             if(!symantec.itools.util.GeneralUtils.objectsEqual(tempItem, text))
  790.             {
  791.                 String oldValue = tempItem.sText;
  792.                 vetos.fireVetoableChange("Text", oldValue, text);
  793.  
  794.                 tempItem.sText = text;
  795.                 tempItem.bDirty = true;
  796.                 tempItem.updateWidth(fm);
  797.                 updateWidth(tempItem);
  798.                 if (!bInternalBlockPaint)
  799.                     repaint();
  800.  
  801.                 changes.firePropertyChange("Text", oldValue, text);
  802.             }
  803.         }
  804.     }
  805.  
  806.     /**
  807.      * Gets the item text associated with the specified zero-relative index.
  808.      * @param index the zero-relative position of the item
  809.      * @return the item text, or null if the index is invalid
  810.      * @see #setText
  811.      */
  812.     public String getText(int index)
  813.     {
  814.         if (validIndex(index))
  815.             return ((ListItem)items.elementAt(index)).sText;
  816.         else
  817.             return null;
  818.     }
  819.  
  820.     /**
  821.      * @deprecated
  822.      * @see #getText
  823.      */
  824.     public String getItem(int index)
  825.     {
  826.         return getText(index);
  827.     }
  828.  
  829.     /**
  830.      * Sets the URL of the image to display at the given zero based index
  831.      * @param aURL the image URL
  832.      * @exception java.net.MalformedURLException
  833.      * if the URL parameter is bad
  834.      * @exception PropertyVetoException
  835.      * if the specified property value is unacceptable
  836.      * @see #getImage
  837.      */
  838.     public void setImageURL(int index, URL aUrl) throws java.net.MalformedURLException, PropertyVetoException
  839.     {
  840.         if (validIndex(index)) {
  841.             ListItem tempItem = ((ListItem)items.elementAt(index));
  842.             URL oldValue = tempItem.url;
  843.             Image image = getToolkit().getImage(aUrl);
  844.             if (image != null)
  845.             {
  846.                 setImage(index, image);
  847.             }
  848.             tempItem.url = aUrl;
  849.             changes.firePropertyChange("ImageURL", oldValue, aUrl);
  850.         }
  851.     }
  852.  
  853.     /**
  854.      * Gets the URL of the image displayed at the given zero-based index.
  855.      * @param index the zero-relative index of the image to get
  856.      * @return the URL of the image
  857.      * @see #setImage
  858.      */
  859.     public URL getImageURL(int index)
  860.     {
  861.         if (validIndex(index))
  862.             return ((ListItem)items.elementAt(index)).url;
  863.         else
  864.             return null;
  865.     }
  866.  
  867.     /**
  868.      * Change the image associated with an item at a
  869.      * specific zero-relative index.
  870.      * @param index the zero-relative position of the item
  871.      * @param image the image to associate with an item
  872.      * @exception PropertyVetoException
  873.      * if the specified property value is unacceptable
  874.      * @see #getImage(int)
  875.      */
  876.     public void setImage(int index, Image image) throws PropertyVetoException
  877.     {
  878.         if (validIndex(index))
  879.         {
  880.             ListItem tempItem = ((ListItem)items.elementAt(index));
  881.  
  882.             if(!symantec.itools.util.GeneralUtils.objectsEqual(tempItem, image))
  883.             {
  884.                 Image oldValue = tempItem.image;
  885.                 vetos.fireVetoableChange("Image", oldValue, image);
  886.  
  887.                 tempItem.image = image;
  888.                 tempItem.bDirty = true;
  889.                 if (!bInternalBlockPaint)
  890.                     repaint();
  891.  
  892.                 changes.firePropertyChange("Image", oldValue, image);
  893.             }
  894.         }
  895.     }
  896.  
  897.     /**
  898.      * Gets the image associated with the specified zero-relative index.
  899.      * @param index the zero-relative position of the item
  900.      * @return the image at the index, or null if the index is invalid
  901.      * @see #setImage(int, java.awt.Image)
  902.      */
  903.     public Image getImage(int index)
  904.     {
  905.         if (validIndex(index))
  906.             return ((ListItem)items.elementAt(index)).image;
  907.         else
  908.             return null;
  909.     }
  910.  
  911.     /**
  912.      * Sets the slelection state of the first item in the list which has exactly
  913.      * matching text.
  914.      * @param str the String to select in the list
  915.      * @exception PropertyVetoException
  916.      * if the specified property value is unacceptable
  917.      * @see getSelectedItem
  918.      */
  919.     public synchronized void setSelectedItem(String str, boolean isSelected) throws PropertyVetoException
  920.     {
  921.         ListItem li;
  922.         int z = items.size();
  923.         for (int i = 0; i < z; i++)
  924.         {
  925.             li = (ListItem) items.elementAt(i);
  926.  
  927.             if (symantec.itools.util.GeneralUtils.objectsEqual(li.sText, str)/*&& li.bEnabled != isSelected*/)
  928.             {
  929.                 //Make up the new string array before it happens.
  930.                 String[] oldValue = getSelectedItems();
  931.                 Vector tempVect = new Vector(oldValue.length);
  932.                 for(int count = 0; count < oldValue.length; count++)
  933.                     tempVect.insertElementAt(oldValue[count], count);
  934.                 if(isSelected)
  935.                     tempVect.addElement(li.sText);
  936.                 else
  937.                     tempVect.removeElement(li.sText);
  938.                 String[] newValue = new String[tempVect.size()];
  939.                 tempVect.copyInto(newValue);
  940.  
  941.                 vetos.fireVetoableChange("SelectedItems", oldValue, newValue);
  942.  
  943.                 setSelectedIndex(i, isSelected);
  944.  
  945.                 if (!bInternalBlockPaint)
  946.                     repaint();
  947.  
  948.                 changes.firePropertyChange("SelectedItems", oldValue, getSelectedItems());
  949.  
  950.                 return;
  951.             }
  952.         }
  953.     }
  954.  
  955.     /**
  956.      * Returns the currently selected item in the list.
  957.      * If multiple items are selected, the item most recently
  958.      * selected is returned.
  959.      * @return the currently selected item, or null if no item is selected.
  960.      * @see #setSelectedItem
  961.      * @see #getSelectedItems
  962.      * @see #deselect
  963.      * @see #isSelected
  964.      */
  965.     public synchronized String getSelectedItem()
  966.     {
  967.         return (lastSelected < 0) ? null : getItem(lastSelected);
  968.     }
  969.  
  970.     /**
  971.      * Select the item at the specified index.
  972.      * This method deselects all others when multiple
  973.      * selections not enabled.
  974.      * @param index the zero-relative position of the item to select
  975.      * @exception PropertyVetoException
  976.      * if the specified property value is unacceptable
  977.      * @see #getSelectedItem
  978.      * @see #deselect
  979.      * @see #isSelected
  980.      */
  981.     public synchronized void setSelectedIndex(int index, boolean isSelected) throws PropertyVetoException
  982.     {
  983.         ListItem listItem = null;
  984.         if (bMultipleSelections)
  985.         {
  986.             listItem = (ListItem)items.elementAt(index);
  987.  
  988.             //Make up the new int array before it happens.
  989.             int[] oldValue = getSelectedIndexes();
  990.             Vector tempVect = new Vector(oldValue.length);
  991.             for(int count = 0; count < oldValue.length; count++)
  992.                 tempVect.insertElementAt(new Integer(oldValue[count]), count);
  993.             if(isSelected)
  994.                 tempVect.addElement(new Integer(index));
  995.             else
  996.                 tempVect.removeElement(new Integer(index));
  997.             int[] newValue = new int[tempVect.size()];
  998.             for(int count = 0; count < tempVect.size(); count++)
  999.                 newValue[count] = ((Integer)tempVect.elementAt(count)).intValue();
  1000.  
  1001.             vetos.fireVetoableChange("SelectedIndex", oldValue, newValue);
  1002.  
  1003.             if(isSelected) {
  1004.                 try {
  1005.                     deselectAll();
  1006.                 } catch (java.beans.PropertyVetoException e) {}
  1007.             }
  1008.             listItem.bSelected = isSelected;
  1009.             listItem.bDirty = true;
  1010.             if(isSelected)
  1011.                 countSelected++;
  1012.  
  1013.             changes.firePropertyChange("SelectedIndex", oldValue, getSelectedIndexes());
  1014.         }
  1015.         else
  1016.         {
  1017.             int s = items.size();
  1018.  
  1019.             if(index < s && index > -1)
  1020.             {
  1021.                 //Make up the new int array before it happens.
  1022.                 int[] oldValue = getSelectedIndexes();
  1023.                 int[] newValue = new int[0];
  1024.                 if(isSelected)
  1025.                 {
  1026.                      newValue = new int[1];
  1027.                      newValue[0] = index;
  1028.                 }
  1029.  
  1030.                 vetos.fireVetoableChange("SelectedIndexes", oldValue, newValue);
  1031.  
  1032.                 listItem = (ListItem)items.elementAt(index);
  1033.                 boolean wasSelected = listItem.bSelected;
  1034.  
  1035.                 //If they want to select something, we must deselect everything else.
  1036.                 if(isSelected)
  1037.                 {
  1038.                     for(int i = 0; i < s; i++)
  1039.                     {
  1040.                         listItem = (ListItem)items.elementAt(i);
  1041.                         if(listItem.bSelected)
  1042.                         {
  1043.                             listItem.bSelected = false;
  1044.                             listItem.bDirty = true;
  1045.                         }
  1046.                     }
  1047.  
  1048.                     listItem = (ListItem)items.elementAt(index);
  1049.                     listItem.bSelected = true;
  1050.                     if(wasSelected)
  1051.                         listItem.bDirty = false;
  1052.  
  1053.                     countSelected = 1;
  1054.                 }
  1055.                 else
  1056.                 {
  1057.                        listItem.bSelected = false;
  1058.                     if(wasSelected){
  1059.                         listItem.bDirty = true;
  1060.                          countSelected--;
  1061.                      }
  1062.                  }
  1063.  
  1064.                 changes.firePropertyChange("SelectedIndexes", oldValue, getSelectedIndexes());
  1065.             }
  1066.         }
  1067.         lastSelected = index;
  1068.         setVisibleIndex(index);
  1069.         if (!bInternalBlockPaint) repaint();
  1070.     }
  1071.  
  1072.     /**
  1073.      * Gets the zero-relative index of the selected item in the list.
  1074.      * If multiple items are selected, the index of the item most recently
  1075.      * selected is returned.
  1076.      * @return the zero-relative index of the selected item, or -1 if no item is
  1077.      * selected
  1078.      * @see #select
  1079.      * @see #deselect
  1080.      * @see #isSelected
  1081.      */
  1082.     public synchronized int getSelectedIndex()
  1083.     {
  1084.         return lastSelected;
  1085.     }
  1086.  
  1087.     /**
  1088.      * Returns the indexes of all the selected items in the list.
  1089.      * @return an array of the zero-relative indexes of the selected items
  1090.      * @see #select
  1091.      * @see #deselect
  1092.      * @see #isSelected
  1093.      */
  1094.     public synchronized int[] getSelectedIndexes()
  1095.     {
  1096.         int sel[] = new int[countSelected];
  1097.  
  1098.         if (countSelected == 1)
  1099.             sel[0] = lastSelected;
  1100.         else if (countSelected > 1)
  1101.         {
  1102.             int x = 0;
  1103.             int s = items.size();
  1104.             for (int i = 0; i < s; i++)
  1105.             {
  1106.                 ListItem tempItem = (ListItem)items.elementAt(i);
  1107.                 if (tempItem.bSelected)
  1108.                 {
  1109.                     sel[x++] = i;
  1110.                     if (x == countSelected)
  1111.                         break;
  1112.                 }
  1113.             }
  1114.         }
  1115.  
  1116.         return sel;
  1117.     }
  1118.  
  1119.     /**
  1120.      * Returns all of the the selected items in the list.
  1121.      * @return an array of all the selected items in the list
  1122.      * @see #getSelectedItem
  1123.      * @see #setSelectedItem
  1124.      * @see #isSelected
  1125.      */
  1126.     public synchronized String[] getSelectedItems()
  1127.     {
  1128.         String str[] = new String[java.lang.Math.max(1,countSelected)];
  1129.         ListItem tempItem;
  1130.  
  1131.         if (!bMultipleSelections)
  1132.         {
  1133.             if (lastSelected != -1)
  1134.             {
  1135.                 tempItem = (ListItem)items.elementAt(lastSelected);
  1136.                 str[0] = tempItem.sText;
  1137.             }
  1138.         }
  1139.         else if (countSelected > 0)
  1140.         {
  1141.             int x = 0;
  1142.             int s = items.size();
  1143.             for (int i = 0; i < s; i++)
  1144.             {
  1145.                 tempItem = (ListItem)items.elementAt(i);
  1146.                 if (tempItem.bSelected)
  1147.                 {
  1148.                     str[x] = tempItem.sText;
  1149.                     if (++x == countSelected)
  1150.                         break;
  1151.                 }
  1152.             }
  1153.         }
  1154.  
  1155.         return str;
  1156.     }
  1157.  
  1158.     /**
  1159.      * Returns the selected items in the list.
  1160.      * Needed in order to implement the java.awt.ItemSelectable interface
  1161.      * @return an array of selected items in the list, as an array of Objects.
  1162.      * @see #getSelectedItem
  1163.      * @see #setSelectedItem
  1164.      * @see #isSelected
  1165.      * @see java.awt.ItemSelectable
  1166.      */
  1167.     public Object[] getSelectedObjects()
  1168.     {
  1169.         return getSelectedItems();
  1170.     }
  1171.  
  1172.     /**
  1173.      * Get the selected state of the item at the given index.
  1174.      * @param index the zero-relative index of the item to be checked
  1175.      * @return true if the item at the specified index
  1176.      * is selected; false if it is not selected
  1177.      * @see #select
  1178.      * @see #deselect
  1179.      * @see #isSelected
  1180.      */
  1181.     public synchronized boolean isSelected(int index)
  1182.     {
  1183.         if (validIndex(index))
  1184.         {
  1185.             ListItem listItem = (ListItem)items.elementAt(index);
  1186.             return listItem.bSelected;
  1187.         }
  1188.         return false;
  1189.     }
  1190.  
  1191.     /**
  1192.      * Sets the current list box label.
  1193.      * @param label the new list box label
  1194.      * @exception PropertyVetoException
  1195.      * if the specified property value is unacceptable
  1196.      * @see #getLabel
  1197.      */
  1198.     public synchronized void setLabel(String label) throws PropertyVetoException
  1199.     {
  1200.         if(!symantec.itools.util.GeneralUtils.objectsEqual(ilbLabel, label))
  1201.         {
  1202.             String oldValue = ilbLabel;
  1203.             vetos.fireVetoableChange("Label", oldValue, label);
  1204.  
  1205.             ilbLabel = label;
  1206.  
  1207.             changes.firePropertyChange("Label", oldValue, label);
  1208.         }
  1209.     }
  1210.  
  1211.     /**
  1212.      * Returns the current list box label.
  1213.      * @return the current list box label
  1214.      * @see #setLabel
  1215.      */
  1216.     public synchronized String getLabel()
  1217.     {
  1218.         return new String(ilbLabel);
  1219.     }
  1220.  
  1221.     /**
  1222.      * Forces the item at the specified index to be visible in
  1223.      * the window.
  1224.      * @param index the zero-relative position of the item to be
  1225.      * made visible
  1226.      * @exception PropertyVetoException
  1227.      * if the specified property value is unacceptable
  1228.      * @see #getVisibleIndex
  1229.      */
  1230.     public synchronized void setVisibleIndex(int index) throws PropertyVetoException
  1231.     {
  1232.         if(visibleIndex != index)
  1233.         {
  1234.             Integer oldValue = new Integer(visibleIndex);
  1235.             Integer newValue = new Integer(index);
  1236.             vetos.fireVetoableChange("VisibleIndex", oldValue, newValue);
  1237.  
  1238.             visibleIndex = index;
  1239.             if ( nTopRow > index )
  1240.                 scrollVertical(index, true);
  1241.             else if (index >= (nTopRow + visibleRows))
  1242.                 scrollVertical(index - visibleRows + 1, true);
  1243.  
  1244.             changes.firePropertyChange("VisibleIndex", oldValue, newValue);
  1245.         }
  1246.     }
  1247.  
  1248.     /**
  1249.      * Gets the index of the item that was last made visible by
  1250.      * the method makeVisible.
  1251.      * @return the zero-relative index of the item last made visible by the
  1252.      * makeVisible method
  1253.      * @see #makeVisible
  1254.      */
  1255.     public int getVisibleIndex()
  1256.     {
  1257.         return visibleIndex;
  1258.     }
  1259.  
  1260.     /**
  1261.      * Forces the item at the specified index to be visible at
  1262.      * the top of the window.
  1263.      * @param index the zero-relative position of the item
  1264.      * @exception PropertyVetoException
  1265.      * if the specified property value is unacceptable
  1266.      * @see #getTopRow
  1267.      */
  1268.     public void setTopRow(int index) throws PropertyVetoException
  1269.     {
  1270.         int s = items.size();
  1271.         if (s < visibleRows)
  1272.             index = 0;
  1273.         else if (index > (s - visibleRows))
  1274.             index = s - visibleRows;
  1275.  
  1276.         if (nTopRow != index)
  1277.         {
  1278.             Integer oldValue = new Integer(nTopRow);
  1279.             Integer newValue = new Integer(index);
  1280.             vetos.fireVetoableChange("TopRow", oldValue, newValue);
  1281.  
  1282.             nTopRow = index;
  1283.             bAllDirty = true;
  1284.             invalidate();
  1285.  
  1286.             changes.firePropertyChange("TopRow", oldValue, newValue);
  1287.         }
  1288.     }
  1289.  
  1290.     /**
  1291.      * Returns the index of the item visible at
  1292.      * the top of the window.
  1293.      * @return index the zero-relative position of the item
  1294.      * @see #setTopRow
  1295.      */
  1296.     public synchronized int getTopRow()
  1297.     {
  1298.         return nTopRow;
  1299.     }
  1300.  
  1301.     /**
  1302.      * Sets the number of columns to be used by getMinimumSize().
  1303.      * @param columns the number of columns
  1304.      * @exception PropertyVetoException
  1305.      * if the specified property value is unacceptable
  1306.      * @see #getColumns
  1307.      */
  1308.     public synchronized void setColumns(int columns) throws PropertyVetoException
  1309.     {
  1310.         if (colsToShow != columns)
  1311.         {
  1312.             Integer oldValue = new Integer(colsToShow);
  1313.             Integer newValue = new Integer(columns);
  1314.             vetos.fireVetoableChange("Columns", oldValue, newValue);
  1315.  
  1316.             colsToShow = columns;
  1317.             invalidate();
  1318.  
  1319.             changes.firePropertyChange("Columns", oldValue, newValue);
  1320.         }
  1321.     }
  1322.  
  1323.     /**
  1324.      * Returns the number of columns to be used by minimumSize().
  1325.      * @return the number of columns
  1326.      * @see #setColumns
  1327.      */
  1328.     public synchronized int getColumns()
  1329.     {
  1330.         return colsToShow;
  1331.     }
  1332.  
  1333.     /**
  1334.      * Returns the number of currently visible lines in this list.
  1335.      * @return the number of visible lines in the list.
  1336.      */
  1337.     public int getRows()
  1338.     {
  1339.         return visibleRows;
  1340.     }
  1341.  
  1342.     /**
  1343.      * Set the font for the items in the list box.
  1344.      * @param f new font to use for list box items
  1345.      */
  1346.     public synchronized void setFont(Font f)
  1347.     {
  1348.         super.setFont(f);
  1349.  
  1350.         f = getFont();
  1351.         if (f != null)
  1352.         {
  1353.             fm = getFontMetrics(f);
  1354.             updateWidths(fm);
  1355.             xCoord = 0;
  1356.  
  1357.             bAllDirty = true;
  1358.             invalidate();
  1359.         }
  1360.     }
  1361.  
  1362.     /**
  1363.      * Set the list to be "dirty" (true) to force a complete
  1364.      * paint on next repaint, or "clean" (false) to avoid a complete
  1365.      * paint on the next repaint.
  1366.      * @param isDirty true if the list is dirty (needs repaint)
  1367.      * @exception PropertyVetoException
  1368.      * if the specified property value is unacceptable
  1369.      * @see #isDirty
  1370.      */
  1371.     public synchronized void setDirty(boolean isDirty) throws PropertyVetoException
  1372.     {
  1373.         Boolean oldValue = new Boolean(bAllDirty);
  1374.         Boolean newValue = new Boolean(isDirty);
  1375.  
  1376.         vetos.fireVetoableChange("Dirty", oldValue, newValue);
  1377.  
  1378.         bAllDirty = isDirty;
  1379.  
  1380.         changes.firePropertyChange("Dirty", oldValue, newValue);
  1381.     }
  1382.  
  1383.     /**
  1384.      * Query the lists all "dirty" state
  1385.      * @return true if on the next repaint the entire list will be
  1386.      * repainted, or false if the list will not be repainted.
  1387.      * @see #setDirty(boolean)
  1388.      */
  1389.     public synchronized boolean isDirty()
  1390.     {
  1391.         return bAllDirty;
  1392.     }
  1393.  
  1394.     /**
  1395.      * @deprecated
  1396.      * @see #setDirty(boolean)
  1397.      * @exception PropertyVetoException
  1398.      * if the specified property value is unacceptable
  1399.      */
  1400.     public synchronized void setDirty() throws PropertyVetoException
  1401.     {
  1402.         setDirty(true);
  1403.     }
  1404.  
  1405.     /**
  1406.      * Query if all rows are selected.
  1407.      * @return returns true if all rows in the ImageListBox
  1408.      * are selected
  1409.      */
  1410.     public boolean isAllSelected()
  1411.     {
  1412.         return (countSelected == items.size());
  1413.     }
  1414.  
  1415.     /**
  1416.      * @deprecated
  1417.      * @see #isAllSelected
  1418.      */
  1419.     public boolean allSelected()
  1420.     {
  1421.         return isAllSelected();
  1422.     }
  1423.  
  1424.     /**
  1425.      * Adds an item to the end of the list and enables the item.
  1426.      * @param item the item to be added
  1427.      * @exception PropertyVetoException
  1428.      * if the specified property value is unacceptable
  1429.      * @see #setListItems(java.lang.String[])
  1430.      * @see #addItem(java.lang.String, boolean)
  1431.      * @see #addItem(java.awt.Image, java.lang.String)
  1432.      * @see #addItem(java.awt.Image, java.lang.String, boolean)
  1433.      * @see #addItem(java.awt.Image, java.lang.String, boolean, java.awt.Color)
  1434.      */
  1435.     public synchronized void addItem(String item) throws PropertyVetoException
  1436.     {
  1437.         addItem(new ListItem((Image)null, item, true, fm, bCellBorders));
  1438.     }
  1439.  
  1440.     /**
  1441.      * Adds an item to the end of the list and conditionally enables
  1442.      * it.
  1443.      * @param item the item to be added
  1444.      * @param bEnabled if true, enable the item; if false, disable
  1445.      * the item
  1446.      * @exception PropertyVetoException
  1447.      * if the specified property value is unacceptable
  1448.      * @see #setListItems(java.lang.String[])
  1449.      * @see #addItem(java.lang.String)
  1450.      * @see #addItem(java.awt.Image, java.lang.String)
  1451.      * @see #addItem(java.awt.Image, java.lang.String, boolean)
  1452.      * @see #addItem(java.awt.Image, java.lang.String, boolean, java.awt.Color)
  1453.      */
  1454.     public synchronized void addItem(String item, boolean bEnabled) throws PropertyVetoException
  1455.     {
  1456.         addItem(new ListItem((Image)null, item, bEnabled, fm, bCellBorders));
  1457.     }
  1458.  
  1459.     /**
  1460.      * Adds an item with an image to the end of the list and enables
  1461.      * it.
  1462.      * @param image the image to display on the item line
  1463.      * @param item the item to be added
  1464.      * @exception PropertyVetoException
  1465.      * if the specified property value is unacceptable
  1466.      * @see #setListItems(java.lang.String[])
  1467.      * @see #addItem(java.lang.String)
  1468.      * @see #addItem(java.lang.String, boolean)
  1469.      * @see #addItem(java.awt.Image, java.lang.String, boolean)
  1470.      * @see #addItem(java.awt.Image, java.lang.String, boolean, java.awt.Color)
  1471.      */
  1472.     public synchronized void addItem(Image image, String item) throws PropertyVetoException
  1473.     {
  1474.         addItem(new ListItem(image, item, true, fm, bCellBorders));
  1475.     }
  1476.  
  1477.     /**
  1478.      * Adds an item with an image to the end of the list and
  1479.      * conditionally enables it.
  1480.      * @param image the image to display on item line
  1481.      * @param item the item to be added
  1482.      * @param bEnabled if true, enable the item; if false, disable the item
  1483.      * @exception PropertyVetoException
  1484.      * if the specified property value is unacceptable
  1485.      * @see #setListItems(java.lang.String[])
  1486.      * @see #addItem(java.lang.String)
  1487.      * @see #addItem(java.lang.String, boolean)
  1488.      * @see #addItem(java.awt.Image, java.lang.String)
  1489.      * @see #addItem(java.awt.Image, java.lang.String, boolean, java.awt.Color)
  1490.      */
  1491.     public synchronized void addItem(Image image, String item, boolean bEnabled) throws PropertyVetoException
  1492.     {
  1493.         addItem(new ListItem(image, item, bEnabled, fm, bCellBorders));
  1494.     }
  1495.  
  1496.     /**
  1497.      * Adds an item with an image to the end of the list and
  1498.      * conditionally enables it. The item text will be displayed in the
  1499.      * given color.
  1500.      * @param image the image to display on item line
  1501.      * @param item the item to be added
  1502.      * @param bEnabled if true, enable the item; if false, disable the item
  1503.      * @param color the color of the item's text
  1504.      * @exception PropertyVetoException
  1505.      * if the specified property value is unacceptable
  1506.      * @see #setListItems(java.lang.String[])
  1507.      * @see #addItem(java.lang.String)
  1508.      * @see #addItem(java.lang.String, boolean)
  1509.      * @see #addItem(java.awt.Image, java.lang.String)
  1510.      * @see #addItem(java.awt.Image, java.lang.String, boolean)
  1511.      */
  1512.     public synchronized void addItem(Image image, String item, boolean bEnabled, Color color) throws PropertyVetoException
  1513.     {
  1514.         ListItem li = new ListItem(image, item, bEnabled, fm, bCellBorders);
  1515.         li.color = color;
  1516.         addItem(li);
  1517.     }
  1518.  
  1519.     /**
  1520.      * Inserts an item with an image at a specific zero-relative index and
  1521.      * conditionally enables it.
  1522.      * @param index the zero-relative index to insert at
  1523.      * @param image the image to display on the item line
  1524.      * @param item the item to be added
  1525.      * @param bEnabled if true, enable the item; if false, disable the item
  1526.      */
  1527.     public synchronized void insertItem(int index, Image image, String item, boolean bEnabled)
  1528.     {
  1529.         ListItem li = null;
  1530.         if ( validIndex(index) )
  1531.         {
  1532.             items.insertElementAt(li = new ListItem(image, item, bEnabled, fm, bCellBorders), index);
  1533.             bAllDirty = true;
  1534.             if (lastSelected >= index)
  1535.                 lastSelected++;
  1536.         }
  1537.         else
  1538.             items.addElement(li = new ListItem(image, item, bEnabled, fm, bCellBorders));
  1539.         updateWidth(li);
  1540.  
  1541.         if (!bInternalBlockPaint) repaint();
  1542.     }
  1543.  
  1544.     /**
  1545.      * Inserts a vector list of items at a specific zero-relative index and
  1546.      * conditionally enables them.
  1547.      * Each item will be displayed with the given image.
  1548.      * @param index the zero-relative index to insert at
  1549.      * @param itemVector the item vector to be added
  1550.      * @param image the image to display for all inserted items
  1551.      * @param bEnabled if true, enable the items; if false, disable the items
  1552.      * @exception PropertyVetoException
  1553.      * if the specified property value is unacceptable
  1554.      */
  1555.     public synchronized void insertItems(int index, Vector itemVector, Image image, boolean bEnabled) throws PropertyVetoException
  1556.     {
  1557.         int s = itemVector.size();
  1558.         int x = 0;
  1559.         int idx = index;
  1560.         if ( validIndex(index) )
  1561.         {
  1562.             for (x = 0; x < s; x++)
  1563.                 items.insertElementAt(new ListItem(image, (String) itemVector.elementAt(x), bEnabled, fm, bCellBorders), index++);
  1564.         }
  1565.         else
  1566.         {
  1567.             for (x = 0; x < s; x++)
  1568.                 items.addElement(new ListItem(image, (String) itemVector.elementAt(x), bEnabled, fm, bCellBorders));
  1569.         }
  1570.         deselectAll();
  1571.         bAllDirty = true;
  1572.         updateWidths(fm);
  1573.  
  1574.         if (!bInternalBlockPaint) repaint();
  1575.     }
  1576.  
  1577.     /**
  1578.      * Returns the total number of items in the list.
  1579.      * @return the number of items in the list
  1580.      * @see #getItem
  1581.      */
  1582.     public int countItems()
  1583.     {
  1584.         return items.size();
  1585.     }
  1586.  
  1587.     /**
  1588.      * @deprecated
  1589.      * @see #setImage(int, java.awt.Image)
  1590.      * @exception PropertyVetoException
  1591.      * if the specified property value is unacceptable
  1592.      */
  1593.     public void changeImage(int index, Image image) throws PropertyVetoException
  1594.     {
  1595.         setImage(index, image);
  1596.     }
  1597.  
  1598.     /**
  1599.      * @deprecated
  1600.      * @see #setText(int, java.lang.String)
  1601.      * @exception PropertyVetoException
  1602.      * if the specified property value is unacceptable
  1603.      */
  1604.     public void changeText(int index, String text) throws PropertyVetoException
  1605.     {
  1606.         setText(index, text);
  1607.     }
  1608.  
  1609.     /**
  1610.      * @deprecated
  1611.      * @see #isMultipleSelections
  1612.      */
  1613.     public boolean allowsMultipleSelections()
  1614.     {
  1615.         return isMultipleSelections();
  1616.     }
  1617.  
  1618.     /**
  1619.      * @deprecated
  1620.      * @see #setEnabled(int, boolean)
  1621.      * @exception PropertyVetoException
  1622.      * if the specified property value is unacceptable
  1623.      */
  1624.     public void enable(int index, boolean cond) throws PropertyVetoException
  1625.     {
  1626.         setEnabled(index, cond);
  1627.     }
  1628.  
  1629.     /**
  1630.      * @deprecated
  1631.      * @see #setEnabled(int, boolean)
  1632.      * @exception PropertyVetoException
  1633.      * if the specified property value is unacceptable
  1634.      */
  1635.     public void enable(int index) throws PropertyVetoException
  1636.     {
  1637.         setEnabled(index, true);
  1638.     }
  1639.  
  1640.     /**
  1641.      * @deprecated
  1642.      * @see #setEnabled(int, boolean)
  1643.      * @exception PropertyVetoException
  1644.      * if the specified property value is unacceptable
  1645.      */
  1646.     public void disable(int index) throws PropertyVetoException
  1647.     {
  1648.         setEnabled(index, false);
  1649.     }
  1650.  
  1651.    /**
  1652.      * Clears the list.
  1653.      * @see #delItem
  1654.      * @see #delItems
  1655.      */
  1656.     public synchronized void clear()
  1657.     {
  1658.         items = new Vector();
  1659.  
  1660.         nTopRow = 0;
  1661.         visibleIndex = -1;
  1662.         lastDownModifiers = -1;
  1663.         lastSelected = -1;
  1664.         lastIndex = -1;
  1665.         lastTempIndex = -1;
  1666.         countSelected = 0;
  1667.         prevSelectTime = -1;
  1668.         prevSelectRow = -1;
  1669.         VBar.setValues(1, 1, 0, 2);
  1670.         VBar.hide();
  1671.         bVBarVisible = false;
  1672.         HBar.setValues(1, 1, 0, 2);
  1673.         HBar.hide();
  1674.         bHBarVisible = false;
  1675.         bAllDirty = true;
  1676.         bInternalBlockPaint = false;
  1677.         bBlockPaint = false;
  1678.         longestLineValue = 0;
  1679.         xCoord = 0;
  1680.         repaint();
  1681.     }
  1682.  
  1683.     /**
  1684.      * Delete an item from the list.
  1685.      * @param index the zero-relative index of the item to delete
  1686.      * @exception PropertyVetoException
  1687.      * if the specified property value is unacceptable
  1688.      * @see #delItems
  1689.      * @see #delSelectedItems
  1690.      */
  1691.     public synchronized void delItem(int index) throws PropertyVetoException
  1692.     {
  1693.         if (validIndex(index))
  1694.         {
  1695.             String[] oldValue = getListItems();
  1696.             String[] newValue = new String[oldValue.length - 1];
  1697.             Vector tempVect = new Vector(oldValue.length);
  1698.             for(int count = 0; count < oldValue.length; count++)
  1699.                 tempVect.insertElementAt(new String(oldValue[count]), count);
  1700.             tempVect.removeElementAt(index);
  1701.             for(int count = 0; count < tempVect.size(); count++)
  1702.                 newValue[count] = new String((String)tempVect.elementAt(count));
  1703.  
  1704.             vetos.fireVetoableChange("ListItems", oldValue, newValue);
  1705.  
  1706.             setSelectedIndex(index, false);
  1707.             if (!bInternalBlockPaint) repaint();
  1708.             items.removeElementAt(index);
  1709.             bAllDirty = true;
  1710.             scrollVertical(nTopRow, true);
  1711.             updateWidths(null);
  1712.             if (!bInternalBlockPaint) repaint();
  1713.  
  1714.             changes.firePropertyChange("ListItems", oldValue, getListItems());
  1715.         }
  1716.     }
  1717.  
  1718.     /**
  1719.      * Delete multiple items from the list.
  1720.      * Note that the end index must be greater than or
  1721.      * equal to the start index.
  1722.      * @param start the zero-relative start index of the items
  1723.      * @param end the zero-relative end index of the items
  1724.      * @exception PropertyVetoException
  1725.      * if the specified property value is unacceptable
  1726.      * @see #delItem
  1727.      * @see #delSelectedItems
  1728.      */
  1729.     public synchronized void delItems(int start, int end) throws PropertyVetoException
  1730.     {
  1731.         int s = items.size();
  1732.         if (s > 0)
  1733.         {
  1734.             if (end >= s)
  1735.                 end = s - 1;
  1736.             if (start < 0)
  1737.                 start = 0;
  1738.             if (start <= end)
  1739.             {
  1740.                 String[] oldValue = getListItems();
  1741.                 String[] newValue = new String[oldValue.length - (end - start) - 1];
  1742.                 Vector tempVect = new Vector(newValue.length);
  1743.                 for(int count = 0; count < start; count++)
  1744.                     tempVect.insertElementAt(new Integer(oldValue[count]), count);
  1745.                 for(int count = end + 1; count < oldValue.length; count ++)
  1746.                     tempVect.insertElementAt(new String(oldValue[count]), start + (count - (end + 1)));
  1747.                 for(int count = 0; count < tempVect.size(); count++)
  1748.                     newValue[count] = new String((String)tempVect.elementAt(count));
  1749.  
  1750.                 vetos.fireVetoableChange("ListItems", oldValue, newValue);
  1751.  
  1752.                 bInternalBlockPaint = true;
  1753.                 for (int i = end; i >= start; i--)
  1754.                 {
  1755.                     setSelectedIndex(i, false);
  1756.                     items.removeElementAt(i);
  1757.                 }
  1758.                 bInternalBlockPaint = false;
  1759.                 bAllDirty = true;
  1760.                 scrollVertical(nTopRow, true);
  1761.                 updateWidths(null);
  1762.                 repaint();
  1763.  
  1764.                 changes.firePropertyChange("ListItems", oldValue, getListItems());
  1765.  
  1766.             }
  1767.         }
  1768.     }
  1769.  
  1770.     /**
  1771.      * Deletes the currently selected items from the list.
  1772.      * @exception PropertyVetoException
  1773.      * if the specified property value is unacceptable
  1774.      * @see #delItem
  1775.      * @see #delItems
  1776.      */
  1777.     public synchronized void delSelectedItems() throws PropertyVetoException
  1778.     {
  1779.         int s = items.size();
  1780.  
  1781.         bInternalBlockPaint = true;
  1782.         for (int x = 0; x < s; )
  1783.         {
  1784.             ListItem tempItem = (ListItem) items.elementAt(x);
  1785.             if (tempItem.bSelected)
  1786.             {
  1787.                 //setSelectedIndex(x, false);
  1788.                 delItem(x);
  1789.                 s--;
  1790.             }
  1791.             else
  1792.                 x++;
  1793.         }
  1794.  
  1795.         bAllDirty = true;
  1796.         scrollVertical(nTopRow, true);
  1797.         updateWidths(null);
  1798.         bInternalBlockPaint = false;
  1799.         repaint();
  1800.     }
  1801.  
  1802.     /**
  1803.      * @deprecated
  1804.      * @see #setSelectedIndex(int, boolean)
  1805.      * @exception PropertyVetoException
  1806.      * if the specified property value is unacceptable
  1807.      */
  1808.     public synchronized void select(int index) throws PropertyVetoException
  1809.     {
  1810.         setSelectedIndex(index, true);
  1811.     }
  1812.  
  1813.     /**
  1814.      * @deprecated
  1815.      * @see #setSelectedItem(java.lang.String, boolean)
  1816.      * @exception PropertyVetoException
  1817.      * if the specified property value is unacceptable
  1818.      */
  1819.     public synchronized void select(String str) throws PropertyVetoException
  1820.     {
  1821.         setSelectedItem(str, true);
  1822.     }
  1823.  
  1824.     /**
  1825.      * Selects an item at the specified index in a multiple-selection-enabled ImageListBox
  1826.      * using Shift, Ctrl or Ctrl-Shift modifiers to mimic mouse
  1827.      * selecting with the Shift, Ctrl or Ctrl-Shift modifiers.
  1828.      * @param index the zero-relative position of the item to select
  1829.      * @param bShift whether to select with the Shift modifier
  1830.      * @param bControl whether to select with the Ctrl modifier
  1831.      * @exception PropertyVetoException
  1832.      * if the specified property value is unacceptable
  1833.      */
  1834.     public synchronized void selectMultiple(int index, boolean bShift, boolean bControl) throws PropertyVetoException
  1835.     {
  1836.         if (!bMultipleSelections)
  1837.         {
  1838.             bShift = false;
  1839.             bControl = false;
  1840.         }
  1841.         if (bShift)
  1842.             shiftSelect(index, bControl);
  1843.         else if (bControl)
  1844.             ctrlSelect(index);
  1845.         else
  1846.             setSelectedIndex(index, true);
  1847.     }
  1848.  
  1849.     /**
  1850.      * Selects all the items in the list.
  1851.      * @see #select
  1852.      * @see #deselectAll
  1853.      */
  1854.     public synchronized void selectAll()
  1855.     {
  1856.         if (!bMultipleSelections)
  1857.             return;
  1858.  
  1859.         int s = items.size();
  1860.         ListItem li;
  1861.         for (int i = 0; i < s; i++)
  1862.         {
  1863.             li = (ListItem)items.elementAt(i);
  1864.             if (li.bEnabled)
  1865.                 li.bSelected = true;
  1866.         }
  1867.         countSelected = s;
  1868.         lastSelected = s - 1;
  1869.         repaint();
  1870.     }
  1871.  
  1872.     /**
  1873.      * @deprecated
  1874.      * @see #setSelectedIndex(int, boolean)
  1875.      * @exception PropertyVetoException
  1876.      * if the specified property value is unacceptable
  1877.      */
  1878.     public synchronized void deselect(int index) throws PropertyVetoException
  1879.     {
  1880.         if (validIndex(index))
  1881.         {
  1882.             setSelectedIndex(index, false);
  1883.             if (!bInternalBlockPaint) repaint();
  1884.         }
  1885.     }
  1886.  
  1887.     /**
  1888.      * Deselects all items in the list.
  1889.      * @exception PropertyVetoException
  1890.      * if the specified property value is unacceptable
  1891.      * @see #selectAll
  1892.      */
  1893.     public synchronized void deselectAll() throws PropertyVetoException
  1894.     {
  1895.         int[] oldValue = getSelectedIndexes();
  1896.         int[] newValue = new int[0];
  1897.          vetos.fireVetoableChange("SelectedIndexes", oldValue, newValue);
  1898.  
  1899.         ListItem li;
  1900.         if (!bMultipleSelections)
  1901.         {
  1902.             if (lastSelected != -1)
  1903.             {
  1904.                 li = (ListItem)items.elementAt(lastSelected);
  1905.                 li.bSelected = false;
  1906.                 li.bDirty = true;
  1907.             }
  1908.         }
  1909.         else
  1910.         {
  1911.             int s = items.size();
  1912.             for (int i = 0; i < s; i++)
  1913.             {
  1914.                 li = (ListItem)items.elementAt(i);
  1915.                 if (li.bSelected)
  1916.                 {
  1917.                     li.bSelected = false;
  1918.                     li.bDirty = true;
  1919.                 }
  1920.             }
  1921.         }
  1922.         lastSelected = -1;
  1923.         countSelected = 0;
  1924.         repaint();
  1925.  
  1926.         changes.firePropertyChange("SelectedIndexes", oldValue, getSelectedIndexes());
  1927.     }
  1928.  
  1929.     /**
  1930.      * @deprecated
  1931.      * @see #setVisibleIndex
  1932.      * @exception PropertyVetoException
  1933.      * if the specified property value is unacceptable
  1934.      */
  1935.     public synchronized void makeVisible(int index) throws PropertyVetoException
  1936.     {
  1937.         setVisibleIndex(index);
  1938.     }
  1939.  
  1940.     /**
  1941.      * Get the height of an individual row.
  1942.      * @return the height in pixels
  1943.      */
  1944.     public int getCellHeight()
  1945.     {
  1946.         return cellHt;
  1947.     }
  1948.  
  1949.     /**
  1950.      * Get the width of the border around the component.
  1951.      * This value is the number of pixels needed to display the border
  1952.      * completely on both sides of the component; it is not the width of
  1953.      * one side of the border.
  1954.      * @return the width in pixels
  1955.      */
  1956.     public int getBorderWidth()
  1957.     {
  1958.         return borderWidth;
  1959.     }
  1960.  
  1961.     /**
  1962.      * Returns the preferred dimensions needed for the list with
  1963.      * the specified number of rows.
  1964.      * @param rows the number of visible rows in the list
  1965.      * @return the preferred size to show the specified number of rows
  1966.      */
  1967.     public Dimension getPreferredSize(int rows)
  1968.     {
  1969.         Dimension d = getMinimumSize(rows);
  1970.         Dimension s = size();
  1971.         return new Dimension(Math.max(d.width, s.width), Math.max(d.height, s.height));
  1972.     }
  1973.  
  1974.     /**
  1975.      * Returns the recommended dimensions to properly display this component.
  1976.      * This is a standard Java AWT method which gets called to determine
  1977.      * the recommended size of this component.
  1978.      *
  1979.      * The size returned is big enough to show the maximum number of visible
  1980.      * rows as requested when constructed, or all the rows currently in the list.
  1981.      *
  1982.      * @see #minimumSize
  1983.      */
  1984.     public Dimension getPreferredSize()
  1985.     {
  1986.         if (rowsToShow > 0)
  1987.             return getPreferredSize(rowsToShow);
  1988.  
  1989.         return getPreferredSize(items.size());
  1990.     }
  1991.  
  1992.     /**
  1993.      * Returns the minimum dimensions needed to show the given number of rows
  1994.      * in the list.
  1995.      * @param rows the number of visible rows in the list
  1996.      * @return the minimum size of this list to show the given number of rows
  1997.      */
  1998.     public Dimension getMinimumSize(int rows)
  1999.     {
  2000.         font = getFont();
  2001.         if (font != null)
  2002.         {
  2003.             fm = getFontMetrics(font);
  2004.             if (fm != null)
  2005.             {
  2006.                 fontHeight = fm.getHeight();
  2007.  
  2008.                 if (bCellBorders)
  2009.                     cellHt = fontHeight+5;
  2010.                 else
  2011.                     cellHt = fontHeight+1;
  2012.  
  2013.                 return new Dimension( ((fm.stringWidth("WN") * colsToShow) / 2) + LINE_SLOP, (rows * cellHt + borderWidth) );
  2014.             }
  2015.         }
  2016.         return new Dimension(borderWidth + LINE_SLOP, borderWidth);
  2017.     }
  2018.  
  2019.     /**
  2020.      * Returns the minimum dimensions to properly display this component.
  2021.      * This is a standard Java AWT method which gets called to determine
  2022.      * the minimum size of this component.
  2023.      *
  2024.      * The size returned is big enough to show the maximum number of visible
  2025.      * rows as requested when constructed, or all the rows currently in the list.
  2026.      *
  2027.      * @see #preferredSize
  2028.      */
  2029.     public Dimension getMinimumSize()
  2030.     {
  2031.         if (rowsToShow > 0)
  2032.             return getMinimumSize(rowsToShow);
  2033.         return getMinimumSize(items.size());
  2034.     }
  2035.  
  2036.     /**
  2037.      * @deprecated
  2038.      * @see #getPreferredSize(int)
  2039.      */
  2040.     public Dimension preferredSize(int rows)
  2041.     {
  2042.         return getPreferredSize(rows);
  2043.     }
  2044.  
  2045.     /**
  2046.      * @deprecated
  2047.      * @see #getPreferredSize
  2048.      */
  2049.     public Dimension preferredSize()
  2050.     {
  2051.         return getPreferredSize();
  2052.     }
  2053.  
  2054.     /**
  2055.      * @deprecated
  2056.      * @see #getMinimumSize(int)
  2057.      */
  2058.     public Dimension minimumSize(int rows)
  2059.     {
  2060.         return getMinimumSize(rows);
  2061.     }
  2062.  
  2063.     /**
  2064.      * @deprecated
  2065.      * @see #getMinimumSize
  2066.      */
  2067.     public Dimension minimumSize()
  2068.     {
  2069.         return getMinimumSize();
  2070.     }
  2071.  
  2072.     /**
  2073.      * Tells this component that it has been added to a container.
  2074.      * This is a standard Java AWT method which gets called by the AWT when
  2075.      * this component is added to a container. Typically, it is used to
  2076.      * create this component's peer.
  2077.      *
  2078.      * It has been overridden here to hook-up event listeners.
  2079.      * It is also used to handle list metrics after the peer is created.
  2080.      *
  2081.      * @see #removeNotify
  2082.      */
  2083.     public synchronized void addNotify()
  2084.     {
  2085.         super.addNotify();
  2086.         errors = ResourceBundle.getBundle("symantec.itools.resources.ErrorsBundle");
  2087.  
  2088.         //Calculate the default width of a scrollbar.
  2089.            barSize = VBar.getPreferredSize().width;
  2090.  
  2091.         //Hook up listeners
  2092.         if (mouse == null)
  2093.         {
  2094.             mouse = new Mouse();
  2095.             addMouseListener(mouse);
  2096.         }
  2097.         if (mouseMotion == null)
  2098.         {
  2099.             mouseMotion = new MouseMotion();
  2100.             addMouseMotionListener(mouseMotion);
  2101.         }
  2102.         if (key == null)
  2103.         {
  2104.             key = new Key();
  2105.             addKeyListener(key);
  2106.         }
  2107.         if (adjustment == null)
  2108.         {
  2109.             adjustment = new Adjustment();
  2110.             VBar.addAdjustmentListener(adjustment);
  2111.             HBar.addAdjustmentListener(adjustment);
  2112.         }
  2113.  
  2114.         font = getFont();
  2115.         fm = getFontMetrics(font);
  2116.         fontHeight = fm.getHeight();
  2117.         updateWidths(fm);
  2118.     }
  2119.     
  2120.     public boolean isFocusTraversable()
  2121.     {
  2122.         return (true);
  2123.     }
  2124.  
  2125.     /**
  2126.      * Tells this component that it is being removed from a container.
  2127.      * This is a standard Java AWT method which gets called by the AWT when
  2128.      * this component is removed from a container. Typically, it is used to
  2129.      * destroy the peers of this component and all its subcomponents.
  2130.      *
  2131.      * It has been overridden here to unhook event listeners.
  2132.      *
  2133.      * @see #addNotify
  2134.      */
  2135.     public synchronized void removeNotify()
  2136.     {
  2137.         //Unhook listeners
  2138.         if (mouse != null)
  2139.         {
  2140.             removeMouseListener(mouse);
  2141.             mouse = null;
  2142.         }
  2143.         if (mouseMotion != null)
  2144.         {
  2145.             removeMouseMotionListener(mouseMotion);
  2146.             mouseMotion = null;
  2147.         }
  2148.         if (key != null)
  2149.         {
  2150.             removeKeyListener(key);
  2151.             key = null;
  2152.         }
  2153.         if (adjustment != null)
  2154.         {
  2155.             VBar.removeAdjustmentListener(adjustment);
  2156.             HBar.removeAdjustmentListener(adjustment);
  2157.             adjustment = null;
  2158.         }
  2159.  
  2160.         super.removeNotify();
  2161.     }
  2162.  
  2163.     /**
  2164.      * Blocks the repainting of the control.
  2165.      * @param cond true to prevent updating the component, false for normal
  2166.      * painting behavior
  2167.      */
  2168.     public synchronized void blockPaint(boolean cond)
  2169.     {
  2170.         bBlockPaint = cond;
  2171.         if (!bBlockPaint)
  2172.             repaint();
  2173.     }
  2174.  
  2175.     /**
  2176.      * Scrolls the ImageListBox vertically.
  2177.      * @param info either an absolute value or Event.SCROLL_PAGE_DOWN,
  2178.      * Event.SCROLL_PAGE_UP, Event.SCROLL_LINE_DOWN, Event.SCROLL_LINE_UP.
  2179.      * The range for an absolute value should be between 0 and (number of rows-1).
  2180.      * @param bAbsolute true to treat the info parameter as an absolute value,
  2181.      * false to treat it as one of the SCROLL_... constants
  2182.      */
  2183.     public synchronized void scrollVertical(int info, boolean bAbsolute)
  2184.     {
  2185.         int temp = nTopRow;
  2186.  
  2187.         if (visibleRows == 0)
  2188.             temp = 0;
  2189.         else
  2190.         {
  2191.             if (bAbsolute)
  2192.                 temp = info;
  2193.             else
  2194.             {
  2195.                 switch (info)
  2196.                 {
  2197.                     case AdjustmentEvent.BLOCK_DECREMENT:       temp -= visibleRows; break;
  2198.                     case AdjustmentEvent.BLOCK_INCREMENT:       temp += visibleRows; break;
  2199.                     case AdjustmentEvent.UNIT_DECREMENT:        temp -= 1; break;
  2200.                     case AdjustmentEvent.UNIT_INCREMENT:        temp += 1; break;
  2201.                 }
  2202.             }
  2203.  
  2204.             if (temp < 0)
  2205.                 temp = 0;
  2206.             else if (temp > (items.size() - visibleRows))
  2207.             {
  2208.                 temp = items.size() - visibleRows;
  2209.                 if (temp < 0)
  2210.                     temp = 0;
  2211.             }
  2212.         }
  2213.  
  2214.         if (nTopRow != temp)
  2215.         {
  2216.             nTopRow = temp;
  2217.             VBar.setValue(temp);
  2218.             bAllDirty = true;
  2219.             if (!bInternalBlockPaint) repaint();
  2220.         }
  2221.     }
  2222.  
  2223.     /**
  2224.      * Scrolls the ImageListBox horizontally
  2225.      * @param info either an absolute value or Event.SCROLL_PAGE_DOWN,
  2226.      * Event.SCROLL_PAGE_UP, Event.SCROLL_LINE_DOWN, Event.SCROLL_LINE_UP.
  2227.      * The range for absolute value should be between 0 and the width of the
  2228.      * largest item, in pixels
  2229.      * @param bAbsolute true to treat the info parameter as an absolute value,
  2230.      * false to treat it as one of the SCROLL_... constants
  2231.      */
  2232.     public synchronized void scrollHorizontal(int info, boolean bAbsolute)
  2233.     {
  2234.         int temp = xCoord;
  2235.  
  2236.         if (bAbsolute)
  2237.             temp = -info;
  2238.         else
  2239.         {
  2240.             switch (info)
  2241.             {
  2242.                 case AdjustmentEvent.BLOCK_DECREMENT:       temp += lWidth; break;
  2243.                 case AdjustmentEvent.BLOCK_INCREMENT:       temp -= lWidth; break;
  2244.                 case AdjustmentEvent.UNIT_DECREMENT:        temp += 1; break;
  2245.                 case AdjustmentEvent.UNIT_INCREMENT:        temp -= 1; break;
  2246.             }
  2247.         }
  2248.  
  2249.         if (temp > 0)
  2250.             temp = 0;
  2251.         else if ( (-temp) > HBar.getMaximum() - lWidth)
  2252.             temp = -(HBar.getMaximum() - lWidth);
  2253.  
  2254.         if (xCoord != temp)
  2255.         {
  2256.             xCoord = temp;
  2257.             HBar.setValue(-temp);
  2258.             bAllDirty = true;
  2259.             if (!bInternalBlockPaint) repaint();
  2260.         }
  2261.     }
  2262.  
  2263.     /**
  2264.      * Handles redrawing of this component on the screen.
  2265.      * This is a standard Java AWT method which gets called by the Java
  2266.      * AWT (repaint()) to handle repainting this component on the screen.
  2267.      * The graphics context clipping region is set to the bounding rectangle
  2268.      * of this component and its [0,0] coordinate is this component's
  2269.      * top-left corner.
  2270.      * Typically this method paints the background color to clear the
  2271.      * component's drawing space, sets graphics context to be the foreground
  2272.      * color, and then calls paint() to draw the component.
  2273.      *
  2274.      * It is overridden here to prevent the flicker associated with the standard
  2275.      * update() method's repainting of the background before painting the component
  2276.      * itself,
  2277.      * and to allow the blocking of painting entirely.
  2278.      *
  2279.      * @param g the graphics context
  2280.      * @see java.awt.Component#repaint
  2281.      * @see #paint
  2282.      */
  2283.     public synchronized void update(Graphics g)
  2284.     {
  2285.         if (!bBlockPaint && !bInternalBlockPaint)
  2286.             paint(g);
  2287.     }
  2288.  
  2289.     /**
  2290.      * Paints this component using the given graphics context.
  2291.      * This is a standard Java AWT method which typically gets called
  2292.      * by the AWT to handle painting this component. It paints this component
  2293.      * using the given graphics context. The graphics context clipping region
  2294.      * is set to the bounding rectangle of this component and its [0,0]
  2295.      * coordinate is this component's top-left corner.
  2296.      *
  2297.      * @param g the graphics context used for painting
  2298.      * @see java.awt.Component#repaint
  2299.      * @see #update
  2300.      */
  2301.     public synchronized void paint(Graphics g)
  2302.     {
  2303.         ListItem item;
  2304.  
  2305.         int nItems;
  2306.         int xSelectStartLoc;
  2307.         int i, j, rows;
  2308.         int vWid = 0;
  2309.         int hHt = 0;
  2310.         int gridAdj = 0;
  2311.         int yLoc = 0;
  2312.         int ySLoc = 0;
  2313.         boolean bShowV = false;
  2314.         boolean bShowH = false;
  2315.  
  2316.         //Make sure cached colors are correct.
  2317.         Color curBackground = getBackground();
  2318.         if (!symantec.itools.util.GeneralUtils.objectsEqual(curBackground, cachedBackground))
  2319.         {
  2320.             cachedBackground = curBackground;
  2321.             calculateBorderColors(curBackground);
  2322.         }
  2323.  
  2324.         // Size size of ListBox
  2325.         Rectangle rect = bounds();
  2326.         font = g.getFont();
  2327.         fm = g.getFontMetrics(font);
  2328.         fontHeight = fm.getHeight();
  2329.         fontDescent = fm.getDescent();
  2330.  
  2331.         nItems = items.size();
  2332.  
  2333.         if (bCellBorders)
  2334.             cellHt = fontHeight+5;
  2335.         else
  2336.             cellHt = fontHeight+1;
  2337.  
  2338.         if (nItems == 0)
  2339.         {
  2340.             nTopRow = 0;
  2341.             visibleRows = 0;
  2342.             bShowH = false;
  2343.             bShowV = false;
  2344.             xCoord = 0;
  2345.         }
  2346.         else
  2347.         {
  2348.             if ( bAllowShowHBar && (longestLineValue > (rect.width - borderWidth)) )
  2349.             {
  2350.                 bShowH = true;
  2351.                 hHt = barSize;
  2352.             }
  2353.             else
  2354.             {
  2355.                 bShowH = false;
  2356.                 hHt = 0;
  2357.             }
  2358.  
  2359.             rows = (rect.height - hHt - borderWidth) / cellHt;
  2360.  
  2361.             if ( bAllowShowVBar && (nItems > rows) )
  2362.             {
  2363.                 bShowV = true;
  2364.                 vWid = barSize;
  2365.                 if (!bShowH)
  2366.                 {
  2367.                     if ( bAllowShowHBar && (longestLineValue > (rect.width - borderWidth - vWid)) )
  2368.                     {
  2369.                         bShowH = true;
  2370.                         hHt = barSize;
  2371.                         rows = (rect.height - hHt - borderWidth) / cellHt;
  2372.                     }
  2373.                 }
  2374.             }
  2375.             else
  2376.             {
  2377.                 bShowV = false;
  2378.                 vWid = 0;
  2379.             }
  2380.  
  2381.             if (visibleRows != rows)
  2382.             {
  2383.                 visibleRows = rows;
  2384.                 bAllDirty = true;
  2385.             }
  2386.             if (bShowV)
  2387.             {
  2388.                 VBar.reshape(rect.width - barSize - halfBorderWidth, halfBorderWidth, barSize, rect.height - borderWidth - hHt);
  2389.                 VBar.setValues(nTopRow, visibleRows, 0, nItems);
  2390.                 VBar.setPageIncrement(visibleRows);
  2391.                 lWidth = rect.width - vWid - borderWidth;
  2392.  
  2393.                 if (!bVBarVisible)
  2394.                 {
  2395.                     bVBarVisible = true;
  2396.                     VBar.show();
  2397.                 }
  2398.             }
  2399.             else
  2400.             {
  2401.                 lWidth = rect.width - borderWidth;
  2402.  
  2403.                 if (bVBarVisible)
  2404.                 {
  2405.                     bVBarVisible = false;
  2406.                     VBar.hide();
  2407.                 }
  2408.             }
  2409.  
  2410.             if (bShowH)
  2411.             {
  2412.                 HBar.reshape(halfBorderWidth, rect.height-barSize-halfBorderWidth, rect.width-borderWidth-vWid, barSize);
  2413.                 HBar.setValues(-xCoord, lWidth, 0, longestLineValue);
  2414.                 HBar.setPageIncrement(lWidth);
  2415.  
  2416.                 if (!bHBarVisible)
  2417.                 {
  2418.                     bHBarVisible = true;
  2419.                     HBar.show();
  2420.                 }
  2421.             }
  2422.             else
  2423.             {
  2424.                 if (bHBarVisible)
  2425.                 {
  2426.                     bHBarVisible = false;
  2427.                     HBar.hide();
  2428.                 }
  2429.             }
  2430.         }
  2431.  
  2432.         if (nItems == 0 || bAllDirty)
  2433.         {
  2434.             g.clearRect(halfBorderWidth, halfBorderWidth, rect.width - borderWidth - 1, rect.height - borderWidth - 1);
  2435.         }
  2436.  
  2437.         if (borderType == 0)
  2438.         {
  2439.             g.setColor(borderDarkerColor);
  2440.             g.drawLine(0, 0, rect.width - 1, 0);
  2441.             g.drawLine(0, 0, 0, rect.height - 1);
  2442.  
  2443.             g.setColor(borderDarkColor);
  2444.             g.drawLine(1, 1, rect.width - 2, 1);
  2445.             g.drawLine(1, 1, 1, rect.height - 2);
  2446.  
  2447.             g.setColor(borderLightColor);
  2448.             g.drawLine(1, rect.height - 2, rect.width - 2, rect.height - 2 );
  2449.             g.drawLine(rect.width - 2, 1, rect.width - 2, rect.height - 2 );
  2450.  
  2451.             g.setColor(borderLighterColor);
  2452.             g.drawLine(0, rect.height - 1, rect.width - 1, rect.height - 1 );
  2453.             g.drawLine(rect.width - 1, 0, rect.width - 1, rect.height - 1 );
  2454.         }
  2455.  
  2456.         g.clipRect(halfBorderWidth, halfBorderWidth, lWidth, rect.height - borderWidth);
  2457.  
  2458.         if (nTopRow >= nItems)
  2459.             nTopRow -= visibleRows + 1;
  2460.  
  2461.         i = nTopRow;
  2462.         j = Math.min(nTopRow + visibleRows, nItems);
  2463.  
  2464.         for (int dp = 0; i < j && items.size() > 0; ++i, ++dp)
  2465.         {
  2466.             yLoc = ( (dp) * (cellHt) ) + halfBorderWidth;
  2467.             ySLoc = ( (dp + 1) * (cellHt) ) + halfBorderWidth;
  2468.  
  2469.             item = (ListItem)items.elementAt(i);
  2470.             if (item.bDirty || bAllDirty)
  2471.             {
  2472.                 item.bDirty = false;
  2473.                 g.clearRect(halfBorderWidth, yLoc, lWidth, cellHt);
  2474.             }
  2475.  
  2476.             if (item.image != null)
  2477.                 xSelectStartLoc = halfBorderWidth + IMAGE_WIDTH + 2;
  2478.             else
  2479.                 xSelectStartLoc = halfBorderWidth;
  2480.  
  2481.             if (item.bCellBorder)
  2482.                 gridAdj = 2;
  2483.             else
  2484.                 gridAdj = 0;
  2485.  
  2486.             if (item.bSelected)
  2487.             {
  2488.                g.setColor(textHighlight);
  2489.                g.fillRect(xCoord + xSelectStartLoc + gridAdj, yLoc, lWidth-xCoord, cellHt);
  2490.                g.setColor(textHighlightText);
  2491.             }
  2492.             else
  2493.             {
  2494.                 if (item.bEnabled)
  2495.                 {
  2496.                     if (item.color == null)
  2497.                         g.setColor(enabledColor);
  2498.                     else
  2499.                         g.setColor(item.color);
  2500.                 }
  2501.                 else
  2502.                     g.setColor(disabledColor);
  2503.             }
  2504.  
  2505.             g.drawString(item.sText, xCoord + xSelectStartLoc + gridAdj + 2, ySLoc-fontDescent);
  2506.  
  2507.             if (item.image != null)
  2508.                 g.drawImage(item.image, xCoord + halfBorderWidth + gridAdj + 2, yLoc+2, IMAGE_WIDTH, cellHt-3, this);
  2509.  
  2510.             if (item.bCellBorder)
  2511.             {
  2512.                 g.setColor(item.cellBorderColor);
  2513.                 g.drawRect(halfBorderWidth, yLoc, lWidth, cellHt);
  2514.             }
  2515.         }
  2516.  
  2517.         extraPaint(g, rect);
  2518.  
  2519.         bAllDirty = false;
  2520.     }
  2521.  
  2522.     /**
  2523.       * Override this method to add any special painting effects after text and images are painted
  2524.       * @param g the graphics
  2525.       * @param rect the bounding rectangle
  2526.       */
  2527.     public void extraPaint(Graphics g, Rectangle rect)
  2528.     {
  2529.     }
  2530.  
  2531.     /**
  2532.      * Makes this component visible.
  2533.      * This is a standard Java AWT method which gets called to show this
  2534.      * component. If this component was invisible due to a previous hide()
  2535.      * call it make this component visible again.
  2536.      *
  2537.      * @see java.awt.Component#hide
  2538.      */
  2539.     public synchronized void show()
  2540.     {
  2541.         bAllDirty = true;
  2542.         super.show();
  2543.     }
  2544.  
  2545.     /**
  2546.      * Moves and/or resizes this component.
  2547.      * This is a standard Java AWT method which gets called to move and/or
  2548.      * resize this component. Components that are in containers with layout
  2549.      * managers should not call this method, but rely on the layout manager
  2550.      * instead.
  2551.      *
  2552.      * @param x horizontal position in the parent's coordinate space
  2553.      * @param y vertical position in the parent's coordinate space
  2554.      * @param width the new width
  2555.      * @param height the new height
  2556.      */
  2557.     public synchronized void reshape(int x, int y, int width, int height)
  2558.     {
  2559.         bAllDirty = true;
  2560.         super.reshape(x, y, width, height);
  2561.     }
  2562.  
  2563.     //--------------------------------------------------
  2564.     // event methods
  2565.     //--------------------------------------------------
  2566.  
  2567.     /**
  2568.      * Adds the specified item listener to receive item events
  2569.      * @param l the item listener
  2570.      * @see #removeItemListener
  2571.      * @see #sourceItemEvent
  2572.      */
  2573.     public synchronized void addItemListener(ItemListener l)
  2574.     {
  2575.         itemListener = AWTEventMulticaster.add(itemListener, l);
  2576.     }
  2577.  
  2578.     /**
  2579.      * Removes the specified item listener so it no longer receives
  2580.      * item events.
  2581.      * @param l the action listener
  2582.      * @see #addItemListener
  2583.      * @see #sourceItemEvent
  2584.      */
  2585.     public synchronized void removeItemListener(ItemListener l)
  2586.     {
  2587.         itemListener = AWTEventMulticaster.remove(itemListener, l);
  2588.     }
  2589.  
  2590.     /**
  2591.      * Adds the specified action listener to receive action events
  2592.      * from this component.
  2593.      * @param l the action listener
  2594.      */
  2595.     public synchronized void addActionListener(ActionListener l)
  2596.     {
  2597.         actionListener = AWTEventMulticaster.add(actionListener, l);
  2598.     }
  2599.  
  2600.     /**
  2601.      * Removes the specified action listener so it no longer receives
  2602.      * action events from this component.
  2603.      * @param l the action listener
  2604.      */
  2605.     public synchronized void removeActionListener(ActionListener l)
  2606.     {
  2607.         actionListener = AWTEventMulticaster.remove(actionListener, l);
  2608.     }
  2609.  
  2610.     /**
  2611.      * Adds a listener for all event changes.
  2612.      * @param PropertyChangeListener listener the listener to add.
  2613.      * @see #removePropertyChangeListener
  2614.      */
  2615.     public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
  2616.     {
  2617.         changes.addPropertyChangeListener(listener);
  2618.     }
  2619.  
  2620.     /**
  2621.      * Removes a listener for all event changes.
  2622.      * @param PropertyChangeListener listener the listener to remove.
  2623.      * @see #addPropertyChangeListener
  2624.      */
  2625.     public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
  2626.     {
  2627.         changes.removePropertyChangeListener(listener);
  2628.     }
  2629.  
  2630.     /**
  2631.      * Adds a vetoable listener for all event changes.
  2632.      * @param VetoableChangeListener listener the listener to add.
  2633.      * @see #removeVetoableChangeListener
  2634.      */
  2635.     public synchronized void addVetoableChangeListener(VetoableChangeListener listener)
  2636.     {
  2637.         vetos.addVetoableChangeListener(listener);
  2638.     }
  2639.  
  2640.     /**
  2641.      * Removes a vetoable listener for all event changes.
  2642.      * @param VetoableChangeListener listener the listener to remove.
  2643.      * @see #addVetoableChangeListener
  2644.      */
  2645.     public synchronized void removeVetoableChangeListener(VetoableChangeListener listener)
  2646.     {
  2647.         vetos.removeVetoableChangeListener(listener);
  2648.     }
  2649.  
  2650.     /**
  2651.      * This is the Mouse Event handling innerclass.
  2652.      */
  2653.     class Mouse extends java.awt.event.MouseAdapter implements java.io.Serializable
  2654.     {
  2655.         /**
  2656.          * Handles Mouse Pressed events
  2657.          * @param e the MouseEvent
  2658.          */
  2659.         public void mousePressed(MouseEvent e)
  2660.         {
  2661.             int x = e.getX();
  2662.             int y = e.getY();
  2663.             int index = -1;
  2664.  
  2665.             requestFocus();
  2666.             fastDownCount++;
  2667.             bMouseDrawHandled = false;
  2668.  
  2669.             if ( (x > -1) && (x < lWidth) )
  2670.             {
  2671.                 index = mouseCalcIndex(y);
  2672.                 if (index == -1)
  2673.                     return;
  2674.  
  2675.                 if (bMultipleSelections)
  2676.                 {
  2677.                     if(e.isShiftDown() && e.isControlDown())
  2678.                     {
  2679.                         bMouseDrawHandled = true;
  2680.                         try { shiftSelect(index, true); } catch(PropertyVetoException exc) {}
  2681.                     }
  2682.                     else if(e.isShiftDown())
  2683.                     {
  2684.                         bMouseDrawHandled = true;
  2685.                         try { shiftSelect(index, false); } catch(PropertyVetoException exc) {}
  2686.                     }
  2687.                     else if(e.isControlDown())
  2688.                     {
  2689.                         bMouseDrawHandled = true;
  2690.                         ctrlSelect(index);
  2691.                     }
  2692.                     else
  2693.                     {
  2694.                         try { setSelectedIndex(index, true); } catch(PropertyVetoException exc) {}
  2695.                     }
  2696.                 }
  2697.                 else
  2698.                 {
  2699.                     lastTempIndex = index;
  2700.                     try { setSelectedIndex(index, true); } catch(PropertyVetoException exc) {}
  2701.                 }
  2702.                 repaint();
  2703.             }
  2704.         }
  2705.  
  2706.         /**
  2707.          * Handles Mouse Released events
  2708.          * @param e the MouseEvent
  2709.          */
  2710.         public void mouseReleased(MouseEvent e)
  2711.         {
  2712.             int x = e.getX();
  2713.             int y = e.getY();
  2714.             int index = -1;
  2715.             boolean bDoubleClick;
  2716.             long selectTime;
  2717.  
  2718.             fastDownCount--;
  2719.             if (bMouseDrawHandled) // multi-selected ctrl or shift
  2720.             {
  2721.                 notifyHelper(-1, y, -1, false);
  2722.                 return;
  2723.             }
  2724.  
  2725.             index = mouseCalcIndex(y);
  2726.             if ( (index == -1) || (x < 0) || (x >= lWidth) )
  2727.             {
  2728.                 fastDownCount = 0;
  2729.                 index = lastTempIndex;
  2730.                 if (index == -1)
  2731.                     return;
  2732.             }
  2733.  
  2734.             if (bComboMode)
  2735.             {
  2736.                 fastDownCount = 0;
  2737.                 bDoubleClick = false;
  2738.             }
  2739.             else
  2740.             {
  2741.                 // sometimes you get two MOUSE_DOWNS before the first MOUSE_UP
  2742.                 if (fastDownCount > 0)
  2743.                 {
  2744.                     fastDownCount = 0;
  2745.                     bDoubleClick = true;
  2746.                     prevSelectTime = -1;
  2747.                     prevSelectRow = -1;
  2748.                 }
  2749.                 else
  2750.                 {
  2751.                     selectTime = System.currentTimeMillis();
  2752.                     if ( (prevSelectTime != -1) &&              // valid prevSelectTime
  2753.                          (prevSelectRow == index) &&            //
  2754.                          ((prevSelectTime + 250) > selectTime)  // A double click
  2755.                       )
  2756.                     {
  2757.                         bDoubleClick = true;
  2758.                         prevSelectTime = -1;
  2759.                         prevSelectRow = -1;
  2760.                     }
  2761.                     else
  2762.                     {
  2763.                         bDoubleClick = false;
  2764.                         prevSelectTime = selectTime;
  2765.                         prevSelectRow = index;
  2766.                     }
  2767.                 }
  2768.             }
  2769.             if (lastSelected != index)
  2770.             {
  2771.                 try { setSelectedIndex(index, true); } catch(PropertyVetoException exc) {}
  2772.                 repaint();
  2773.             }
  2774.             if (bMultipleSelections)
  2775.             {
  2776.                 notifyHelper(x, y, lastSelected, bDoubleClick);
  2777.                 lastIndex = lastSelected;
  2778.             }
  2779.             else
  2780.             {
  2781.                 notifyHelper(x, y, index, bDoubleClick);
  2782.                 lastIndex = index;
  2783.             }
  2784.             lastTempIndex = -1;
  2785.             lastDownModifiers = -1;
  2786.         }
  2787.  
  2788.         /**
  2789.          * Handles Mouse Exited events
  2790.          * @param e the MouseEvent
  2791.          */
  2792.         public void mouseExited(MouseEvent e)
  2793.         {
  2794.             if (!bMultipleSelections && bComboMode)
  2795.                 lastIndex = -1;
  2796.         }
  2797.     }
  2798.  
  2799.     /**
  2800.      * This is the MouseMotion Event handling innerclass.
  2801.      */
  2802.     class MouseMotion implements java.awt.event.MouseMotionListener, java.io.Serializable
  2803.     {
  2804.         /**
  2805.          * Handles Mouse Moved events
  2806.          * @param e the MouseEvent
  2807.          */
  2808.         public void mouseMoved(MouseEvent e)
  2809.         {
  2810.             if(!bMultipleSelections)
  2811.             {
  2812.                 int x = e.getX();
  2813.                 int y = e.getY();
  2814.                 int  index = -1;
  2815.  
  2816.                 if ( (x > -1) && (x < lWidth) )
  2817.                 {
  2818.                     if (bComboMode)
  2819.                     {
  2820.                         index = mouseCalcIndex(y);
  2821.                         if (index == -1 || index == lastIndex)
  2822.                             return;
  2823.                         lastIndex = index;
  2824.  
  2825.                         try { setSelectedIndex(index, true); } catch(PropertyVetoException exc) {}
  2826.                         repaint();
  2827.                     }
  2828.                 }
  2829.             }
  2830.         }
  2831.  
  2832.         /**
  2833.          * Handles Mouse Dragged events
  2834.          * @param e the MouseEvent
  2835.          */
  2836.         public void mouseDragged(MouseEvent e)
  2837.         {
  2838.             int x = e.getX();
  2839.             int y = e.getY();
  2840.             int  index = -1;
  2841.  
  2842.             if ( (x > -1) && (x < lWidth) )
  2843.             {
  2844.                 if (bComboMode)
  2845.                 {
  2846.                     index = mouseCalcIndex(y);
  2847.                     if (index == -1 || index == lastIndex)
  2848.                         return;
  2849.                     lastIndex = index;
  2850.  
  2851.                     try { setSelectedIndex(index, true); } catch(PropertyVetoException exc) {}
  2852.                     repaint();
  2853.                 }
  2854.                 else
  2855.                 {
  2856.                     index = mouseCalcIndex(y);
  2857.                     if (index != -1 && index != lastIndex)
  2858.                     {
  2859.                         if (bMultipleSelections)
  2860.                         {
  2861.                             if (e.getModifiers() != 0)
  2862.                                 return;
  2863.  
  2864.                             bInternalBlockPaint = true;
  2865.                             try { setVisibleIndex(index); } catch(PropertyVetoException exc){}
  2866.                             bInternalBlockPaint = false;
  2867.                             try { shiftSelect(index, false); } catch(PropertyVetoException exc) {}
  2868.                         }
  2869.                         else
  2870.                         {
  2871.                             try { setSelectedIndex(index, true); } catch(PropertyVetoException exc) {}
  2872.                         }
  2873.                         lastIndex = index;
  2874.                     }
  2875.                 }
  2876.             }
  2877.         }
  2878.     }
  2879.  
  2880.     /**
  2881.      * This is the Key Event handling innerclass.
  2882.      */
  2883.     class Key extends java.awt.event.KeyAdapter implements java.io.Serializable
  2884.     {
  2885.         /**
  2886.          * Handles Key Pressed events
  2887.          * @param e the KeyEvent
  2888.          */
  2889.         public void keyPressed(KeyEvent e)
  2890.         {
  2891.             if (e.isControlDown() || e.isMetaDown() || e.isAltDown())
  2892.                 return;
  2893.  
  2894.             int index = -1;
  2895.  
  2896.             switch(e.getKeyCode())
  2897.             {
  2898.                 case KeyEvent.VK_HOME:
  2899.                     index = keyCalcIndex(0, true);
  2900.                     break;
  2901.                 case KeyEvent.VK_END:
  2902.                     index = keyCalcIndex(items.size() - 1, true);
  2903.                     break;
  2904.                 case KeyEvent.VK_PAGE_UP:
  2905.                     index = keyCalcIndex(-visibleRows, false);
  2906.                     break;
  2907.                 case KeyEvent.VK_PAGE_DOWN:
  2908.                     index = keyCalcIndex(visibleRows, false);
  2909.                     break;
  2910.                 case KeyEvent.VK_UP:
  2911.                     index = keyCalcIndex(-1, false);
  2912.                     break;
  2913.                 case KeyEvent.VK_DOWN:
  2914.                     index = keyCalcIndex(1, false);
  2915.                     break;
  2916.             }
  2917.             if (index == -1)
  2918.                 return;
  2919.  
  2920.             if (bMultipleSelections && e.isShiftDown())
  2921.             {
  2922.                 try { setVisibleIndex(index); } catch(PropertyVetoException exc){}
  2923.                 try { shiftSelect(index, false); } catch(PropertyVetoException exc){}
  2924.                 return;
  2925.             }
  2926.  
  2927.             // regular select, multiple or single
  2928.             try { setSelectedIndex(index, true); } catch(PropertyVetoException exc) {}
  2929.             repaint();
  2930.             notifyHelper(-1, -1, index, false);
  2931.             prevSelectTime = -1;
  2932.             prevSelectRow = -1;
  2933.         }
  2934.     }
  2935.  
  2936.     /**
  2937.      * This is the Adjustment Event handling innerclass.
  2938.      */
  2939.     class Adjustment implements java.awt.event.AdjustmentListener, java.io.Serializable
  2940.     {
  2941.         /**
  2942.          * Handles ScrollBar events
  2943.          * @param e the AdjustmentEvent
  2944.          */
  2945.         public void adjustmentValueChanged(AdjustmentEvent e)
  2946.         {
  2947.             //We are only listening to the VBar and the HBar...
  2948.             if(e.getSource() == VBar)
  2949.             {
  2950.                 if(e.getAdjustmentType() == AdjustmentEvent.TRACK)
  2951.                     scrollVertical(e.getValue(), true);
  2952.                 else
  2953.                     scrollVertical(e.getAdjustmentType(), false);
  2954.             }
  2955.             else if(e.getSource() == HBar)
  2956.             {
  2957.                 if(e.getAdjustmentType() == AdjustmentEvent.TRACK)
  2958.                     scrollHorizontal(e.getValue(), true);
  2959.                 else
  2960.                     scrollHorizontal(e.getAdjustmentType(), false);
  2961.             }
  2962.         }
  2963.     }
  2964.  
  2965.     /**
  2966.      * Fire an item event to the listeners
  2967.      * @see #addItemListener
  2968.      * @see #removeItemListener
  2969.      */
  2970.     protected void sourceItemEvent()
  2971.     {
  2972.         if (itemListener != null)
  2973.             itemListener.itemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, this, ItemEvent.SELECTED));
  2974.     }
  2975.  
  2976.     /**
  2977.      * Fire an action event to the listeners
  2978.      * @param command the string containing the command to send
  2979.      * with the event.
  2980.      */
  2981.     protected void sourceActionEvent(String command)
  2982.     {
  2983.         if (actionListener != null)
  2984.             actionListener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, command));
  2985.     }
  2986.  
  2987.     /**
  2988.      * Determines if the given index is valid.
  2989.      * @param index a zero-relative index to check
  2990.      * @return true if the index is valid, false if not
  2991.      */
  2992.     protected boolean validIndex(int index)
  2993.     {
  2994.         if (index >= 0 && index < items.size())
  2995.             return true;
  2996.         return false;
  2997.     }
  2998.  
  2999.     /**
  3000.      * Determines if the item at the given index is visible.
  3001.      * @param index the zero-relative index of the item to check
  3002.      * @return true if the item is visible, false if not
  3003.      */
  3004.     protected boolean isVisibleIndex(int index)
  3005.     {
  3006.         if (index >= nTopRow && index < (nTopRow + visibleRows))
  3007.             return true;
  3008.         return false;
  3009.     }
  3010.  
  3011.     /**
  3012.      * Returns a string representing the state of this object.
  3013.      * This is a standard Java AWT method which can be usefull for debugging.
  3014.      *
  3015.      * @return a handy string for debugging purposes
  3016.      */
  3017.     protected String paramString()
  3018.     {
  3019.         return super.paramString() + ", selected=" + getSelectedItem();
  3020.     }
  3021.  
  3022.     /**
  3023.      * Selects an index in a multiple-selection-enabled ImageListBox
  3024.      * using Shift or Ctrl-Shift modifiers to mimic mouse
  3025.      * selecting with the Shift or Ctrl-Shift modifiers.
  3026.      * @param index the zero-relative position of the item to select
  3027.      * @param bControl whether to select with the Ctrl modifier
  3028.      * @exception PropertyVetoException
  3029.      * if the specified property value is unacceptable
  3030.      */
  3031.     protected void shiftSelect(int index, boolean bControl) throws PropertyVetoException
  3032.     {
  3033.         int i = 0;
  3034.         int s = 0;
  3035.         ListItem li;
  3036.  
  3037.         if (lastSelected == -1)
  3038.             setSelectedIndex(index, true);
  3039.         else if (lastSelected == index)
  3040.         {
  3041.             if (!bControl)
  3042.             {
  3043.                 bInternalBlockPaint = true;
  3044.                 setSelectedIndex(index, true);
  3045.                 bInternalBlockPaint = false;
  3046.             }
  3047.         }
  3048.         else if (lastSelected < index)
  3049.         {
  3050.             if ( !isEnabled(index) )
  3051.                 return;
  3052.  
  3053.             if (bControl)
  3054.             {
  3055.                 i = lastSelected + 1;
  3056.                 s = Math.min(items.size(), index + 1);
  3057.             }
  3058.             else
  3059.             {
  3060.                 i = 0;
  3061.                 s = items.size();
  3062.             }
  3063.             for (; i < s; i++)
  3064.             {
  3065.                 li = (ListItem)items.elementAt(i);
  3066.                 if (i < lastSelected || i > index)
  3067.                 {
  3068.                     if (li.bSelected)
  3069.                     {
  3070.                         li.bDirty = true;
  3071.                         li.bSelected = false;
  3072.                         countSelected--;
  3073.                     }
  3074.                 }
  3075.                 else
  3076.                 {
  3077.                     if (!li.bSelected)
  3078.                     {
  3079.                         li.bDirty = true;
  3080.                         li.bSelected = true;
  3081.                         countSelected++;
  3082.                     }
  3083.                 }
  3084.             }
  3085.         }
  3086.         else if (lastSelected > index)
  3087.         {
  3088.             if ( !isEnabled(index) )
  3089.                 return;
  3090.  
  3091.             if (bControl)
  3092.             {
  3093.                 i = index;
  3094.                 s = Math.min(items.size(), lastSelected);
  3095.             }
  3096.             else
  3097.             {
  3098.                 i = 0;
  3099.                 s = items.size();
  3100.             }
  3101.             for (i = 0; i < s; i++)
  3102.             {
  3103.                 li = (ListItem)items.elementAt(i);
  3104.                 if (i < index || i > lastSelected)
  3105.                 {
  3106.                     if (li.bSelected)
  3107.                     {
  3108.                         li.bDirty = true;
  3109.                         li.bSelected = false;
  3110.                         countSelected--;
  3111.                     }
  3112.                 }
  3113.                 else
  3114.                 {
  3115.                     if (!li.bSelected)
  3116.                     {
  3117.                         li.bDirty = true;
  3118.                         li.bSelected = true;
  3119.                         countSelected++;
  3120.                     }
  3121.                 }
  3122.             }
  3123.         }
  3124.         if (!bInternalBlockPaint) repaint();
  3125.     }
  3126.  
  3127.     /**
  3128.      * Selects an index in a ImageListBox using the Ctrl modifier
  3129.      * to mimic mouse selecting with the Ctrl modifier.
  3130.      * @param index the zero-relative position of the item to select
  3131.      */
  3132.     protected void ctrlSelect(int index)
  3133.     {
  3134.         ListItem listItem = (ListItem)items.elementAt(index);
  3135.         if (!listItem.bEnabled)
  3136.             return;
  3137.  
  3138.         if (listItem.bSelected)
  3139.         {
  3140.             listItem.bSelected = false;
  3141.             countSelected--;
  3142.             lastSelected = -1;
  3143.         }
  3144.         else
  3145.         {
  3146.             listItem.bSelected = true;
  3147.             countSelected++;
  3148.             lastSelected = index;
  3149.         }
  3150.         listItem.bDirty = true;
  3151.         if (!bInternalBlockPaint) repaint();
  3152.     }
  3153.  
  3154.     /**
  3155.      * A utility routine that determines the index of the item the mouse is in,
  3156.      * given the vertical coordinate of the mouse.
  3157.      * @param y mouse vertical (y) coordinate
  3158.      * @return the zero-relative index of the item the mouse is in, or -1 if
  3159.      * past the end of the list
  3160.      */
  3161.     protected int mouseCalcIndex(int y)
  3162.     {
  3163.         int mci;
  3164.  
  3165.         if (y < yAdj)
  3166.             mci = nTopRow - 1;
  3167.         else
  3168.             mci = ((y - yAdj) / cellHt) + nTopRow;
  3169.  
  3170.         if (mci >= items.size())
  3171.             mci = -1;
  3172.         else if (mci < 0)
  3173.             mci = 0;
  3174.  
  3175.         return mci;
  3176.     }
  3177.  
  3178.     /**
  3179.      * Adds an ListItem to the end of the list.
  3180.      * @param li the item to add
  3181.      * @exception PropertyVetoException
  3182.      * if the specified property value is unacceptable
  3183.      * @see #setListItems(java.lang.String[])
  3184.      * @see #addItem(java.lang.String)
  3185.      * @see #addItem(java.lang.String, boolean)
  3186.      * @see #addItem(java.awt.Image, java.lang.String)
  3187.      * @see #addItem(java.awt.Image, java.lang.String, boolean)
  3188.      * @see #addItem(java.awt.Image, java.lang.String, boolean, java.awt.Color)
  3189.      */
  3190.     protected void addItem(ListItem li) throws PropertyVetoException
  3191.     {
  3192.         if(li != null)
  3193.         {
  3194.             String[] oldValue = getListItems();
  3195.             String[] newValue = new String[oldValue.length + 1];
  3196.             for(int count = 0; count < oldValue.length; count++)
  3197.                 newValue[count] = new String(oldValue[count]);
  3198.             newValue[oldValue.length] = new String(li.sText);
  3199.  
  3200.             vetos.fireVetoableChange("ListItems", oldValue, newValue);
  3201.  
  3202.             if(nTopRow < 0)
  3203.             {
  3204.                 nTopRow = 0;
  3205.             }
  3206.  
  3207.             items.addElement(li);
  3208.             updateWidth(li);
  3209.             if (!bInternalBlockPaint) repaint();
  3210.             changes.firePropertyChange("ListItems", oldValue, getListItems());
  3211.         }
  3212.     }
  3213.  
  3214.     private void updateWidth(ListItem li)
  3215.     {
  3216.         int lineWidth = li.lineWidth + LINE_SLOP;
  3217.         if (li.image != null)
  3218.             lineWidth += IMAGE_WIDTH;
  3219.         if ( lineWidth > longestLineValue)
  3220.             longestLineValue = lineWidth;
  3221.     }
  3222.  
  3223.     private void updateWidths(FontMetrics fm)
  3224.     {
  3225.         longestLineValue = 0;
  3226.         int s = items.size();
  3227.         int lineWidth = 0;
  3228.         ListItem li;
  3229.         for (int x = 0; x < s; x++)
  3230.         {
  3231.             li = (ListItem)items.elementAt(x);
  3232.             li.updateWidth(fm);
  3233.  
  3234.             lineWidth = li.lineWidth + LINE_SLOP;
  3235.             if (li.image != null)
  3236.                 lineWidth += IMAGE_WIDTH;
  3237.             if ( lineWidth > longestLineValue)
  3238.                 longestLineValue = lineWidth;
  3239.         }
  3240.     }
  3241.  
  3242.     /**
  3243.      * Utility routine to generate action and/or item events in response to
  3244.      * key or mouse events.
  3245.      * @param x mouse component-relative horizontal position, in pixels
  3246.      * @param x mouse component-relative vertical position, in pixels
  3247.      * @param index zero-relative index of currently selected item
  3248.      * @param bDoubleClick true if mouse double-clicked on item
  3249.      */
  3250.     protected void notifyHelper(int x, int y, int index, boolean bDoubleClick)
  3251.     {
  3252.         if (bDoubleClick)
  3253.         {
  3254.             sourceActionEvent("DoubleClicked");
  3255.         }
  3256.         else
  3257.         {
  3258.             //inside image display area, and line has image!
  3259.             if (x >= 0 && (x - xCoord) < IMAGE_WIDTH)
  3260.             {
  3261.                 ListItem listItem = (ListItem)items.elementAt(index);
  3262.                 if (listItem.image != null)
  3263.                 {
  3264.                     sourceActionEvent("ImageSelected");
  3265.                 }
  3266.             }
  3267.             sourceItemEvent();
  3268.         }
  3269.     }
  3270.  
  3271.     /**
  3272.      * Used to calculate the border colors from the background color.
  3273.      * @see #addNotify
  3274.      * @see java.awt.Component#setBackground
  3275.      */
  3276.     protected void calculateBorderColors(Color c)
  3277.     {
  3278.         borderLighterColor    = ColorUtils.calculateHilightColor(c);
  3279.         borderDarkerColor    = ColorUtils.calculateShadowColor(c);
  3280.         borderLightColor    = ColorUtils.darken(borderLighterColor, 0.200);
  3281.         borderDarkColor        = ColorUtils.darken(borderDarkerColor, 0.200);
  3282.     }
  3283.  
  3284.     /**
  3285.      * Determines the current index given a new absolute or relative index.
  3286.      * @param offset the value used to compute the new index
  3287.      * @param boolean true if offset is zero-relative, false if offset is
  3288.      * relative to the current index value
  3289.      * @return the new current index value
  3290.      */
  3291.     protected int keyCalcIndex(int offset, boolean bAbsolute)
  3292.     {
  3293.         if (bAbsolute)
  3294.             lastIndex = offset;
  3295.         else
  3296.             lastIndex += offset;
  3297.  
  3298.         if (lastIndex >= items.size())
  3299.             lastIndex = items.size() - 1;
  3300.         else if (lastIndex < 0)
  3301.             lastIndex = 0;
  3302.  
  3303.         return lastIndex;
  3304.     }
  3305.  
  3306.     private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException
  3307.     {
  3308.         in.defaultReadObject();
  3309.  
  3310.         ListItem li = null;
  3311.         for (int i = 0; i < items.size(); i++)
  3312.         {
  3313.             li = (ListItem) items.elementAt(i);
  3314.             if (li.url != null) {
  3315.                 li.image = getToolkit().getImage(li.url);
  3316.  
  3317.                 java.awt.MediaTracker tracker = new java.awt.MediaTracker(this);
  3318.                 tracker.addImage(li.image, 0);
  3319.                 try {
  3320.                     tracker.waitForAll();
  3321.                 }
  3322.                 catch(InterruptedException e) {
  3323.                     Object[] args = { li.url };
  3324.                     throw new java.io.IOException(MessageFormat.format(errors.getString("ErrorLoadingImageForURL"), args));
  3325.                 }
  3326.             }
  3327.         }
  3328.  
  3329.     }
  3330.     /**
  3331.      * Zero-relative index of the item displayed in the top row.
  3332.      */
  3333.     protected int   nTopRow = 0;
  3334.     /**
  3335.      * Width of the list content portion of this component, in pixels.
  3336.      * This excludes the border and vertical scroll bar, if present.
  3337.      */
  3338.     protected int   lWidth = 0;
  3339.     /**
  3340.      * Height of a single list cell, in pixels.
  3341.      */
  3342.     protected int   cellHt = 0;
  3343.     /**
  3344.      * Top margin before the contents of the first list item, in pixels.
  3345.      */
  3346.     protected int   yAdj = 0;
  3347.     /**
  3348.      * Width of the left and right borders combined, in pixels.
  3349.      */
  3350.     protected int       borderWidth = 4;
  3351.     /**
  3352.      * Width of the left or right border, in pixels.
  3353.      */
  3354.     protected int       halfBorderWidth = 2;
  3355.  
  3356.     ActionListener actionListener = null;
  3357.     ItemListener itemListener = null;
  3358.  
  3359.     /**
  3360.      * Extra space at end of a line.
  3361.      */
  3362.     protected final int LINE_SLOP = 6;
  3363.     /**
  3364.      * The label of this listbox (not displayed).
  3365.      */
  3366.     protected String ilbLabel;
  3367.     /**
  3368.      * The vertical scroll bar. It always exists event if not shown or showable.
  3369.      */
  3370.     protected Scrollbar   VBar = null;
  3371.     /**
  3372.      * The horizontal scroll bar. It always exists event if not shown or showable.
  3373.      */
  3374.     protected Scrollbar   HBar = null;
  3375.     /**
  3376.      * A vector of the items in the list.
  3377.      */
  3378.     protected Vector      items;
  3379.     /**
  3380.      * The font used for drawing text.
  3381.      */
  3382.     protected Font        font;
  3383.     /**
  3384.      * The font metrics of the font used for drawing text.
  3385.      */
  3386.     transient protected FontMetrics fm = null;
  3387.     /**
  3388.      * If true the list is dirty (needs repaint).
  3389.      */
  3390.     transient protected boolean bAllDirty = true;
  3391.     /**
  3392.      * It true multiple list items can be selected at the same time.
  3393.      */
  3394.     protected boolean bMultipleSelections = false;
  3395.     /**
  3396.      * If true the repainting of the control is prevented.
  3397.      */
  3398.     protected boolean bBlockPaint = false;
  3399.     /**
  3400.      * True if the vertical scroll bar is currently visible.
  3401.      */
  3402.     protected boolean bVBarVisible = false;
  3403.     /**
  3404.      * True if the horizontal scroll bar is currently visible.
  3405.      */
  3406.     protected boolean bHBarVisible = false;
  3407.     /**
  3408.      * True if repainting is temporarily disabled for efficiency purposes.
  3409.      */
  3410.     transient protected boolean bInternalBlockPaint = false;
  3411.     /**
  3412.      * The number of rows to show when this component is automatically laid out.
  3413.      * If rows is less than or equal to zero, it will size to show all of the
  3414.      * existing list items when automatically laid out.
  3415.      */
  3416.     protected int     rowsToShow = -1;
  3417.     /**
  3418.      * The number of columns to show when this component is automatically laid out.
  3419.      */
  3420.     protected int     colsToShow = 10;
  3421.     /**
  3422.      * The number of currently visible lines in this list.
  3423.      */
  3424.     transient protected int     visibleRows = -1;
  3425.     /**
  3426.      * The number of currently visible columns in this list.
  3427.      */
  3428.     transient protected int     visibleCols = -1;
  3429.     /**
  3430.      * The zero-relative index of the first visible list item.
  3431.      */
  3432.     protected int     visibleIndex = -1;
  3433.     /**
  3434.      * The standard height of a line of text in the current font.
  3435.      */
  3436.     transient protected int     fontHeight;
  3437.     /**
  3438.      * The typical distance from the base line to the bottom of most characters
  3439.      * in the current font.
  3440.      */
  3441.     transient protected int     fontDescent;
  3442.     /**
  3443.      * Not used.
  3444.      */
  3445.     transient protected int     lastDownModifiers = -1;
  3446.     /**
  3447.      * The zero-relative index of the currently selected item in the list.
  3448.      * If multiple items are selected, this is the index of the item most
  3449.      * recently selected. If no items are selected, the value is -1.
  3450.      */
  3451.     transient protected int     lastSelected = -1;
  3452.     /**
  3453.      * The zero-relative index of the item the mouse was last moved over,
  3454.      * dragged over, or clicked on. This field is only valid while the
  3455.      * mouse is over this component. When the mouse is not over this component
  3456.      * the value is -1.
  3457.      */
  3458.     transient protected int     lastIndex = -1;
  3459.     /**
  3460.      * The zero-relative index of the item the mouse was pressed on.
  3461.      * It is used when bMultipleSelections is false, and valid
  3462.      * between the time the mouse is pressed and released.
  3463.      * All other times it equals -1.
  3464.      */
  3465.     transient protected int     lastTempIndex = -1;
  3466.     /**
  3467.      * The number of list items currently selected.
  3468.      */
  3469.     transient protected int     countSelected = 0;
  3470.     /**
  3471.      * The current border type of this ImageListBox, one of BORDER_REGULAR or
  3472.      * BORDER_NONE.
  3473.      * A regular border makes the list box appear lower than the surrounding area.
  3474.      * @see #getBorderType
  3475.      * @see #BORDER_REGULAR
  3476.      * @see #BORDER_NONE
  3477.      */
  3478.     protected int     borderType = 0;
  3479.     /**
  3480.      * The width of the widest list item, in pixels.
  3481.      */
  3482.     protected int     longestLineValue = 0;
  3483.     /**
  3484.      * The width of scroll bars, in pixels.  Calculated in addNotify.
  3485.      */
  3486.     transient protected int barSize = 0;
  3487.     /**
  3488.      * The amount the list items are scrolled horizontally, in pixels.
  3489.      */
  3490.     protected int     xCoord = 0;
  3491.     /**
  3492.      * The time at which the mouse was released, in milliseconds.
  3493.      * This is used to determine when a double-click occurs.
  3494.      */
  3495.     transient protected long    prevSelectTime = -1;
  3496.     /**
  3497.      * The zero-relative index of the row at which the mouse was
  3498.      * previously released.
  3499.      * This is used to determine when a double-click occurs.
  3500.      */
  3501.     transient protected long    prevSelectRow = -1;
  3502.     /**
  3503.      * If true this ImageListBox is in "ComboBox mode".
  3504.      * "ComboBox mode" allows the selection point to follow
  3505.      * the mouse even when the mouse button is not down.
  3506.      * This only applies when the ImageListBox is not allowing multiple
  3507.      * selections.
  3508.      *
  3509.      * @see #setComboMode
  3510.      */
  3511.     protected boolean bComboMode = false;
  3512.     /**
  3513.      * If true list items have borders by default.
  3514.      * Borders are always shown as a solid single-pixel wide line around
  3515.      * the cell.
  3516.      *
  3517.      * @see #setCellBorders
  3518.      */
  3519.     protected boolean bCellBorders = false;
  3520.     /**
  3521.      * If true the vertical scrollbar will be made
  3522.      * visible when necessary, false if it will never be made visible.
  3523.      * @see #setShowVerticalScroll
  3524.      */
  3525.     protected boolean bAllowShowVBar = true;
  3526.     /**
  3527.      * If true the horizontal scrollbar will be made
  3528.      * visible when necessary, false if it will never be made visible.
  3529.      * @see #setShowHorizontalScroll
  3530.      */
  3531.     protected boolean bAllowShowHBar = true;
  3532.  
  3533.     /**
  3534.      * Color used in drawing of the border.
  3535.      */
  3536.     protected Color borderLighterColor    = null;
  3537.     /**
  3538.      * Color used in drawing of the border.
  3539.      */
  3540.     protected Color borderDarkerColor    = null;
  3541.     /**
  3542.      * Color used in drawing of the border.
  3543.      */
  3544.     protected Color borderLightColor    = null;
  3545.     /**
  3546.      * Color used in drawing of the border.
  3547.      */
  3548.     protected Color borderDarkColor    = null;
  3549.     /**
  3550.      * Cached value of the background color.  Used to determine if calculated colors need to be updated.
  3551.      */
  3552.     protected Color cachedBackground    = null;
  3553.  
  3554.     //!!! LAB !!! Come back and remove this isMacintosh stuff once MRJ handles SystemColor!
  3555.  
  3556.     /**
  3557.      * The background color for highlighted text.
  3558.      */
  3559.     protected Color textHighlight = symantec.itools.lang.OS.isMacintosh() ? new Color(0,0,128) : SystemColor.textHighlight;
  3560.  
  3561.     /**
  3562.      * The text color for highlighted text.
  3563.      */
  3564.     protected Color textHighlightText = symantec.itools.lang.OS.isMacintosh() ? Color.white : SystemColor.textHighlightText;
  3565.  
  3566.     /**
  3567.      * The default color for enabled text items.
  3568.      */
  3569.     protected Color enabledColor = symantec.itools.lang.OS.isMacintosh() ? Color.black : SystemColor.textText;
  3570.     /**
  3571.      * The default color for disabled text items.
  3572.      */
  3573.     protected Color disabledColor = symantec.itools.lang.OS.isMacintosh() ? Color.gray : SystemColor.textInactiveText;
  3574.     /**
  3575.      * Used to detect two mouse pressed events without a mouse released
  3576.      * event in-between. This may sometimes happen if the mouse is pressed
  3577.      * twice very quickly.
  3578.      */
  3579.     protected int fastDownCount = 0;
  3580.     /**
  3581.      * True if drawing was handled on mouse down and no drawing action needs
  3582.      * to be taken on mouse up.
  3583.      */
  3584.     protected boolean bMouseDrawHandled = false;
  3585.     /**
  3586.      * Error strings.
  3587.      */
  3588.     transient protected ResourceBundle errors;
  3589.  
  3590.     private Mouse            mouse        = null;
  3591.     private MouseMotion    mouseMotion    = null;
  3592.     private Key            key            = null;
  3593.     private Adjustment        adjustment    = null;
  3594.     private symantec.itools.beans.VetoableChangeSupport vetos = new symantec.itools.beans.VetoableChangeSupport(this);
  3595.     private symantec.itools.beans.PropertyChangeSupport changes = new symantec.itools.beans.PropertyChangeSupport(this);
  3596. }
  3597.  
  3598.